在不阅读整个文档的情况下插入嵌入的文档 - spring,mongo

Nil*_*noj 12 java mongodb spring-boot

我有这个factory系列:

@Document(collection = "factory")
public class Factory
{
    Private List<Product> products;

}
Run Code Online (Sandbox Code Playgroud)

其中嵌入了Productas 产品。当我必须向现有工厂添加产品时:

@Autowired
private FactoryRepository factoryRepository;

public void addProduct(Long id, Product product) {
    Factory f = factoryRepository.findById(id);
    f.addProduct(product);
    factoryRepository.save(f);

}
Run Code Online (Sandbox Code Playgroud)

然而,问题是,产品是一个大对象,它包含了一组重属性工厂能有2000吨的产品

因此,虽然在此阶段不需要,但检索到的工厂会导致大量内存消耗。有没有办法在不读取整个对象的情况下将新产品对象直接附加到工厂文档中?


编辑:

至于评论,我试过:

public void addProduct(Long id, Product product) {
        Document find = new Document("_id",id);
        Document listItem = new Document("products",product);
        Document push = new Document("$push", listItem);
        collection.updateOne(find,push);
}       
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

org.bson.codecs.configuration.CodecConfigurationException: 
Can't find a codec for class product
Run Code Online (Sandbox Code Playgroud)

所以我修改为在 push 之前将其转换为字符串:

org.bson.codecs.configuration.CodecConfigurationException: 
Can't find a codec for class product
Run Code Online (Sandbox Code Playgroud)

此推送对象正确,但在阅读时:

org.springframework.core.convert.ConverterNotFoundException: 
No converter found capable of converting from type [java.lang.String] to type [Product]
Run Code Online (Sandbox Code Playgroud)

尽管如此,我还是无处可去。关于解决这个问题的任何想法?

use*_*814 6

您应该使用 MongoTemplate 通过推送更新产品以添加到现有产品。就像是

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

@SpringBootApplication
public class So62173077Application {

    public static void main(String[] args) {
        SpringApplication.run(So62173077Application.class, args);
    }

    @Autowired
    private MongoTemplate mongoTemplate;

    @Document(collection = "factory")
    public class Factory
    {
        private Long id;
        private List<Product> products;

    }

    public Long createFactory() {
        Factory factory = new Factory();
        factory.id = 1L;
        return mongoTemplate.insert(factory).id;
    }

    public void addProduct(Long id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        Product product = new Product();
        product.name = "stackoverflow";
        update.push("products", product);
        mongoTemplate.updateFirst(query, update, Factory.class);
    }

    private class Product {
        private String name;
    }

    @Bean
    public ApplicationRunner runner() {
        return args -> {
            //Long id = createFactory();
            addProduct(1L);

        };
    }

}
Run Code Online (Sandbox Code Playgroud)