简体   繁体   English

插入嵌入文档而不阅读整个文档 - spring,mongo

[英]Insert embeded document without reading whole document - spring, mongo

I have this factory collection:我有这个factory收藏:

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

}

which embeds the Product as products.Product嵌入为产品。 When I have to add a product to an existing factory:当我必须向现有工厂添加产品时:

@Autowired
private FactoryRepository factoryRepository;

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

}

However, the issue is that product is a large object which contains a set of heavy attributes and the factory can have 2000 products .然而,问题是产品是一个大的 object 包含一组重属性工厂可以有 2000 个产品

So, the retrieved factory causes large memory consumption although it is not required in this phase.因此,回收的工厂会导致大量 memory 消耗,尽管在此阶段不需要。 Is there a way to append a new product object directly into the factory document without reading the whole object?有没有办法把append 一个新产品object 直接进厂文件不用读整个object?

EDIT:编辑:

As for the comments, I tried:至于评论,我试过:

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);
}       

This gives error:这给出了错误:

org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class product

So I modified to convert it to a string before push:所以我修改为在推送之前将其转换为字符串:

public void addProduct(Long id, Product product) {
        Document find = new Document("_id",id);
        ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
        Document listItem = new Document("products",ow.writeValueAsString(product));
        Document push = new Document("$push", listItem);
        collection.updateOne(find,push);
}     

This pushed object correctly but when reading:这正确地推动了 object 但在阅读时:

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [Product]

Still, I got nowhere here.不过,我在这里无处可去。 Any ideas on fixing this issue?有关解决此问题的任何想法?

You should use MongoTemplate to update product with push to add to existing products.您应该使用 MongoTemplate 通过推送更新产品以添加到现有产品。 Something like就像是

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);

        };
    }

}

MongoDB large array may be discouraged (fetching, atomic operations, complex querying). MongoDB 可能不鼓励使用大型数组(获取、原子操作、复杂查询)。

Depending on your needs but I would suggest you to deal with Product in a brand new "product" collection.根据您的需要,但我建议您在全新的“产品”集合中处理产品。 Your current issue will be solved as well.您当前的问题也将得到解决。

Regards.问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM