在MongoDB文档中添加新字段到对象

时间:2016-02-17 03:40:35

标签: java mongodb

我的MongoDB中有一个包含数千个文档的集合。 每个文档目前都是这样的:

{
    "_id" : ObjectId("1"),
    "FIELD1" : {
        "STR1" : "some text",
        "STR2" : "some text",
        "STR3" : "some text",
        "STR4" : "some text"
    },
    "FIELD2" : "some text"
}

使用以下代码段,我设法为所有4000多个文档添加一个新字段:

// Add new field to all documents   
BasicDBObject query = new BasicDBObject();
BasicDBObject update = new BasicDBObject();
update.put("$set", new BasicDBObject(NEW_DB_FIELD_NAME, new BasicDBObject()));
WriteResult result = coll.update(query, update, true, true);

文档有一个新结构,其中FIELD3Object

{
    "_id" : ObjectId("1"),
    "FIELD1" : {
        "STR1" : "some text",
        "STR2" : "some text",
        "STR3" : "some text",
        "STR4" : "some text"
    },
    "FIELD2" : "some text",
    "FIELD3" : {
    }
}

现在,问题是我希望向FIELD3添加多个项目,其中每个项目都是Object,其中包含2个String s:

{
    "_id" : ObjectId("1"),
    "FIELD1" : {
        "STR1" : "some text",
        "STR2" : "some text",
        "STR3" : "some text",
        "STR4" : "some text"
    },
    "FIELD2" : "some text",
    "FIELD3" : {
        "ITEM1" : {
            "STR1" : "",
            "STR2" : ""
        },
        "ITEM2" : {
            "STR1" : "",
            "STR2" : ""
        },
        "ITEM3" : {
            "STR1" : "",
            "STR2" : ""
        }
    }
}

我试过的是:

BasicDBObject query = new BasicDBObject{"FIELD2","some text"};
BasicDBObject update = new BasicDBObject();
update.put("$set", new BasicDBObject("FIELD3.ITEM1.STR1", "some text").append("FIELD3.ITEM1.STR2", "some text");
result = coll.update(query, update, true, false);

问题是我只能在FIELD3下获得一个新项目。当我遍历项目时,它会不断被新值替换。

请帮忙!

更新

在@Explosion Pills的帮助下,我设法将所有ITEM1ITEM2ITEM3等添加到我新创建的FIELD3中。但是,我现在有另一个问题,即我有'重复'项,其中value字段是相同的。我不希望这样。

删除重复项的优雅方法是什么?或者,更好的是,只插入非重复的优雅方式是什么?

我之前对重复问题不太清楚。事实是,不同的项目必须具有不同的名称,例如ITEM1,ITEM2等;否则,他们互相取代。我想要比较的是value s。

如果我将数据存储在不同的结构中会更好/更容易吗?我在想是否可能将FIELD3更改为ArrayList而不是Object。 目前,它类似于以下内容,我希望通过“WATERMELON”字段删除重复的水果。

FRUITS
   > FRUIT1
       > WATERMELON
       > BIG
   > FRUIT2
       > WaTeRMeLON
       > BIG
   > FRUIT3
       > APPLE
       > SMALL

请帮忙!

2 个答案:

答案 0 :(得分:1)

This post表示要为要创建的每个对象使用单独的selector._domainkey.example.com descriptive text "k=rsa\;p=\010...QAB" 。它很冗长,但我还没有找到另一种方法。

BasicDBObject

答案 1 :(得分:1)

我设法通过更改数据存储结构来解决自己的无重复问题。如果有人有兴趣...

// Creating an ArrayList to store all the different fruits
ArrayList<BasicDBObject> newField = new ArrayList<BasicDBObject>();
for (...) {
    String value = "";
    String type = "";
    BasicDBObject newItem = new BasicDBObject("value", value).append("type", type);
    newField.add(newItem);
}

// Removing duplicates from ArrayList
Set<BasicDBObject> setItems = new LinkedHashSet<BasicDBObject>(newField);
newField.clear();
newField.addAll(setItems);

// Adding ArrayList of fruits into database
BasicDBObject update = new BasicDBObject();
update.put("$set", new BasicDBObject("FRUITS", newField));
WriteResult result = coll.update({"_id":"1"}, update, true, false);

注意:使用LinkedHashSet代替HashSet表示订单已保留。