MongoDB: 更新嵌套数组元素,如果不存在则插入

MongoDB: Update nested array element or insert it if not existing

在我的案例中,文档结构可能是这样的:

{
    "_id" : "P9H59RuSbnm45erj7",
    "description" : [
        {
            "content" : "Something",
            "language" : "en",
            "timestamp" : 1476958705
        },
        {
            "content" : "Irgendetwas",
            "language" : "de",
            "timestamp" : 1476958705
        }
    ]
}

现在我想更新特定语言的内容。 但是 描述数组可能缺少语言。

{
    "_id" : "P9H59RuSbnm45erj7",
    "description" : [
        {
            "content" : "Something",
            "language" : "en",
            "timestamp" : 1476958705
        }
    ]
}

所以我所做的是先检查该语言是否存在,然后

  1. 如果它存在,我会做一个简单的更新/$set
  2. 如果不存在,我会进行更新/$addToSet

我的问题是,这是否可以简化。我真的必须检查现有语言然后使用两个不同的更新查询吗?有了这个,代码就被激发了......

我在我的 meteor 应用程序中使用了这段代码,所以我使用的是 minimongo。

if (Collection.find({ _id: 'P9H59RuSbnm45erj7', 'description.language': 'en' }).count() > 0) {
    Collection.update(
        {
            _id                   : 'P9H59RuSbnm45erj7',
            'description.language': 'en'
        },
        {
            $set: {
                'description.$.content'  : value,
                'description.$.timestamp': Math.floor(Date.now() / 1000)
            }
        }
    );
}
else {
    Collection.update(
        { _id: 'P9H59RuSbnm45erj7' },
        {
            $addToSet: {
                description: {
                    content  : value,
                    language : 'en',
                    timestamp: Math.floor(Date.now() / 1000)
                }
            }
        }
    );
}
db.Test8.update(
      { _id: 1, "description.language":{$eq:"en"} },
      {
                $set: { "description.$.content": "content5" }
      },
      {}, function (err, result) {

          // if result.nMatched == 0 then make your $addToSet
          // because there are no query

       }
    );

在这种情况下使用查询的好处是大部分时间是 1 次查询而不是 2 次查询。很少有时间是 2 次查询。

取决于您最常遇到的情况。 正如你所说的大部分时间是更新,那么你可以进行1次查询而不是2次查询。

我不知道还有什么其他方法可以让它变得更好。