Java 在文档MongoDB中添加或更改节点
我有一个现有文档,可能有也可能没有这样的嵌入式节点“cls”:Java 在文档MongoDB中添加或更改节点,java,mongodb,mongodb-query,Java,Mongodb,Mongodb Query,我有一个现有文档,可能有也可能没有这样的嵌入式节点“cls”: product { _id: .., product_id: "myuniqueid", name: "some name", cls: { some data } } 现在,我需要的是: 如果产品不存在,则什么也不会发生 如果产品存在且cls存在,则更新cls零件 如果产品存在而cls不存在,则将cls部件添加到该产品中 我发现如果我设置upsert=false,什么也不会发生。然而,我倾向于相信ups
product {
_id: ..,
product_id: "myuniqueid",
name: "some name",
cls: { some data }
}
现在,我需要的是:
upsert=false
,什么也不会发生。然而,我倾向于相信upsert
适用于嵌入文档(产品),而不是嵌入文档(cls)
所以基本上我写:
public static UpdateResult upsert(MongoCollection<Document> coll, Bson filter, Document doc, boolean upsert) {
BasicDBObject action = new BasicDBObject("$set", doc);
UpdateOptions options = new UpdateOptions().upsert(upsert);
return coll.updateOne(filter, action, options);
}
它似乎没有更新任何内容,至少在cls还不存在的情况下。因此,upsert
选项几乎适用于cls节点,而不是嵌入产品。MongoDB文档对这一问题不是决定性的
我可能会将upsert
更改为true,并将product\u id作为唯一索引,以确保不会插入任何外来产品。但我真正想要的是一个解释 除非你想在标准不匹配的情况下“创建”一些东西,否则你永远都不会想要。这是唯一的目的,因为您基本上是在说“这是一个‘独特’文档的组成部分,如果您没有找到,请为我创建一个”。这不是你的逻辑所暗示的。事实上,这要简单得多
你真正想要的是:
您将看到的另一件非常好的事情是,如果您想要将“cls”设置为与已有的完全相同,那么实际上,
$set
操作实际上什么都不做,因为更新足够智能,可以意识到它是相同的,并且不会尝试更改数据。它仍然报告“匹配”,但幕后的最新统计数据表明,在这种情况下没有更新。好的!因此,我应该直接将新的BasicDBObject(“cls”,justClsValue)添加到操作中,而不是首先将其添加到嵌入产品中!谢谢很高兴今天我学到了一些东西。@dexter你问题中最大的含糊不清之处是“产品中的数据是什么?”,它只是作为一个神秘的变量出现,没有任何解释。$set
(和其他更新操作符)的要点是,它允许您指定实际要用某些内容更新的“字段路径”,而不是仅仅覆盖整个文档。所以,如果您只想“在我找到产品的地方设置cls”,那么这就是您所要做的。另一个“巨大的歧义”是,“产品”是主文档还是文档中的一系列“嵌入项”?这是一个如何提问的技巧。
product.append("cls", clsDoc);
DBUtil.upsert(products, new BasicDBObject("product_id", pid), product, false);
collection.updateOne(
new BasicDBObject("product_id", pid),
new BasicDBObject("$set",
new BasicDBObject("cls", justClsValue)
)
);