【问题标题】:Upsert nested objects in mongodb 3.2 using Java driver使用 Java 驱动程序在 mongodb 3.2 中插入嵌套对象
【发布时间】:2016-02-21 20:11:08
【问题描述】:

我正在尝试使用 java 使用 mongodb v3.2 的 upsert 功能, 所以不包括 java 响应的所有解决方案都不会被接受。

我的问题是 upsert 命令覆盖嵌套对象而不是添加新对象,我尝试使用 '$addToSet' 和 'push',但没有成功我收到一条错误消息,指出存储引擎不支持此命令。

我想更新客户的文档以及他们的内部对象,例如检查和检查的值。 客户端文档的全局结构如下。

客户 | |__Checks // 检查数组,更新或插入操作 | |__values // 值数组,每个检查都有自己的值(最大 20) // 使用 index(id) 更新

链接:Example's source code

我的意图是只使用一个查询来更新客户的文档,而不使用很多查询。

我不是 mongodb 专家,因此我将不胜感激任何建议或批评。

即使我做错了,请随时通知我,并请使用 java for mongo 3.2

这是用于生成最后一个结果的源代码。

package org.egale.core;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.UpdateOptions;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;

/**
 *
 * @author Zied
 */
public class MongoTest {

    /**
     * Pojo used to populate data
     */
    static class CheckModel {
        public String client;
        public String checkId;
        public String name;
        public String command;
        public String description;
        public String topic;
        public int refresh = 60;
        public int status;
        public String output;
    }

    static MongoClient mongoClient = new MongoClient();
    static String dbName = "eagle";

    private static List<Document> getCheckValues(CheckModel checkModel, int index) {

        final List<Document> checkValues = new ArrayList<>();
        final Document val = new Document()
                .append("id", index)
                .append("output", checkModel.output)
                .append("status", checkModel.status);
        checkValues.add(val); // second execution should not ovveride the content of value but a new 
        return checkValues;
    }

    private static void insertCheck(MongoDatabase db, CheckModel checkModel) {
        int idx =++index % 20;
        final List<Document> checks = new ArrayList<>();
        final Document check = new Document()
                .append("name", checkModel.name)
                .append("command", checkModel.command)
                .append("id", checkModel.checkId)
                .append("description", checkModel.description)
                .append("topic", checkModel.topic)
                .append("last_output", checkModel.output)
                .append("index", index)
                .append("last_status", checkModel.status)
                .append("values", getCheckValues(checkModel,idx))
                .append("refresh", checkModel.refresh);
        checks.add(check);

        Document client = new Document()
                .append("name", checkModel.client)
                .append("checks", checks);
        //.append("$addToSet" , new Document("checks", checks)); // <<- error here '$addToSet' is not recocnized 

        db.getCollection("clients") // execute client insert or update
                .updateOne(
                        new Document().append("_id", checkModel.client), new Document("$set", client), new UpdateOptions().upsert(true)
                );
    }

    static int index = 0;

    // Name of the topic from which we will receive messages from = " testt"
    public static void main(String[] args) {
        MongoDatabase db = mongoClient.getDatabase(dbName);

        CheckModel checkModel = new CheckModel();
        checkModel.command = "ls -lA";
        checkModel.client = "client_001";
        checkModel.description = "ls -l command";
        checkModel.checkId = "lsl_command";
        checkModel.name = "client 001";
        checkModel.output = "result of ls -l";
        checkModel.status = 0;
        checkModel.topic = "basic_checks";
        checkModel.refresh = 5000;

        initDB(db);
        // insert the first check
        insertCheck(db, checkModel);
        // insert the second check after some modification
//        insertCheck(db, modifyData(checkModel));

    }
    // mdofiy data to test the check
    private static CheckModel modifyData(CheckModel checkModel){
        checkModel.status = 1;
        checkModel.output = "ls commadn not found";
        return checkModel;
    }
    private static void initDB(MongoDatabase db) {
        MongoCollection<Document> collection = db.getCollection("configuration");
        if (collection.count() == 0) {
            Document b = new Document()
                    .append("_id", "app_config")
                    .append("historical_data", 20)
                    .append("current_index", 0);
            collection.insertOne(b);
        }

        Document b = new Document().append("none", "none");

        MongoCollection<Document> clients = db.getCollection("clients");
        clients.insertOne(b);
        clients.deleteOne(b);

        MongoCollection<Document> topics = db.getCollection("topics");
        topics.insertOne(b);
        topics.deleteOne(b);
    }

}

【问题讨论】:

    标签: java mongodb-java


    【解决方案1】:

    您可以使用 $push、$each、$slice 来解决您的问题,另见 https://docs.mongodb.org/manual/reference/operator/update/slice/

    db.students 有以下文件

    { "_id" : 10, "scores" : [  1, 2, 3 ] }
    
    db.students.update(
       { _id: 10 },
       {
         $push: {
           scores: {
           $each: [ 4 ],
           $slice: -3
         }
       }
     }
    )
    

    结果是:

    { "_id" : 10, "scores" : [  2, 3, 4] }
    

    【讨论】:

    • 感谢您的回复,但这不是我要搜索的内容。??!
    猜你喜欢
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多