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

4

我有一个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);

这份文件有一个新的结构,其中FIELD3是一个Object对象:

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

现在的问题是我希望将多个项添加到FIELD3中,每个项都是一个包含两个StringObject

{
    "_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
如果我将数据存储在不同的结构中,会不会更好/更容易?我在思考,也许应该将FIELD3改为ArrayList而不是Object。 目前,它类似于以下内容,我希望从中删除具有“WATERMELON”字段的重复水果。
FRUITS
   > FRUIT1
       > WATERMELON
       > BIG
   > FRUIT2
       > WaTeRMeLON
       > BIG
   > FRUIT3
       > APPLE
       > SMALL

请帮忙!


我已经更新了我的帖子,更清楚地说明了我的新问题。你能帮忙吗?@Explosion Pills - Tacocat
没事了!我已经想通了,哈哈!@Explosion Pills - Tacocat
2个回答

2

我通过改变数据存储结构成功解决了自己的无重复问题。如果有人感兴趣...

// 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可以保留顺序。

1

这篇文章建议为想要创建的每个对象使用单独的BasicDBObject。虽然有点冗长,但我还没有找到其他方法。

BasicDBObject item1 = new BasicDBObject("STR1", "text").append("STR2", "txt");
// also for item2 and item3...

BasicDBObject field3 = new BasicDBObject("ITEM1", item1).append("ITEM2", item2);

update.put("$set", new BasicDBObject("FIELD3", field3));

好的。没事了。我应该能够适应这个来得到我需要的东西。稍后会尝试一下,谢谢! - Tacocat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接