使用Java驱动程序在mongodb 3.2中嵌套嵌套对象

时间:2016-02-21 20:11:08

标签: java mongodb-java

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

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

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

Client
 |
 |__Checks // array of checks , update or insert operation
    |
    |__values // array of values, every check has its own values (20 max)
              // update using index(id)

的链接:Example's source code

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

我不是mongodb的专家,所以每个建议或评论家都会受到赞赏。

即使我这样做也是错误的,请随时通知我,并请使用 java 进行mongo 3.2

enter image description here

enter image description here

enter image description here

以下是用于生成最后结果的源代码。

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

}

1 个答案:

答案 0 :(得分:-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] }