添加或更改文档MongoDB中的节点

时间:2015-09-04 09:49:07

标签: java mongodb mongodb-query

我有一个现有的文件,可能有也可能没有嵌入式节点" cls"像这样:

product { 
   _id: ..,
   product_id: "myuniqueid",
   name: "some name",
   cls: { some data }
}

现在,我需要的是:

  1. 如果产品不存在,则不会发生任何事情
  2. 如果产品存在且cls存在,则cls部分已更新
  3. 如果产品存在且cls不存在,则将cls部分添加到该产品
  4. 如果我设置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);
    }
    

    然后使用:

    product.append("cls", clsDoc);
    DBUtil.upsert(products, new BasicDBObject("product_id", pid), product, false);
    

    它似乎没有更新任何东西,至少如果cls还不存在。因此,几乎好像upsert选项适用于cls节点而不是嵌入产品。 MongoDB文件在这个问题上没有定论。

    我可能会将upsert更改为true,并将product_id设为唯一索引,以确保不会插入任何外来产品。但我真正想要的是解释。

1 个答案:

答案 0 :(得分:2)

除非您想要&#34;创建&#34;当标准不匹配时,您不希望"upsert"。这是唯一的目的,因为你基本上是在说&#34;这就是什么使得&#39;独特的&#39;文件,如果你没找到,那么为我创建一个&#34; 。这不是你的逻辑所暗示的。事实上它比这简单得多。

你真正想要的只是:

  1. 查找产品或不

  2. 当您找到某些内容时,请将此字段设置为此值

  3. 基本上你自己的第二和第三点可以成为第二点。这里没有任何建议&#34;创建一个未找到的新文档&#34; ,这是&#34; upsert&#34;行为,因此你省略了它。

    基本上,只是$set

    collection.updateOne(
        new BasicDBObject("product_id", pid),
        new BasicDBObject("$set",
            new BasicDBObject("cls", justClsValue)
        )
    );
    

    它真的不能简单,因为那些是基本的机制。

    另一个非常好的事情你会看到你想要设置什么&#34; cls&#34; to与已经存在的完全相同,然后实际上$set操作实际上什么都不做,因为更新足够智能以实现它并且不会尝试更改数据。它仍然报告&#34;匹配&#34;,但幕后更新的统计数据表明在这种情况下没有更新。