Mongodb 在元素不存在的位置插入数组,否则更新它(使用多个条件)

Mongodb 在元素不存在的位置插入数组,否则更新它(使用多个条件),mongodb,mongodb-query,Mongodb,Mongodb Query,如果权重或大小不同,我想在数组中插入新对象,如果大小和权重都匹配,我想更新它。如何执行此操作?与类似,您可以使用,但由于阵列元素选择具有“多个条件”,因此您可以使用: 因此,行动是: 测试中的数组元素匹配条件是否存在,然后测试匹配的值 测试数组元素是否以否定形式存在。您可以在每个属性上交替使用,但是在两个匹配的条件都比较干净的情况下进行否定 db.collection.bulkWrite([ { "updateOne": { "filter"

如果权重或大小不同,我想在数组中插入新对象,如果大小和权重都匹配,我想更新它。如何执行此操作?

与类似,您可以使用,但由于阵列元素选择具有“多个条件”,因此您可以使用:

因此,行动是:

  • 测试中的数组元素匹配条件是否存在,然后测试匹配的值

  • 测试数组元素是否以否定形式存在。您可以在每个属性上交替使用,但是在两个匹配的条件都比较干净的情况下进行否定

    db.collection.bulkWrite([
      { "updateOne": {
        "filter": { 
          "_id": "1", 
          "option": { 
            "$elemMatch": { "weight": "40", "size": "40" }
          }
        },
        "update": { 
          "$set": { "option.$.price": "300" }
        }
      }},
      { "updateOne": {
        "filter": {
          "_id": "1",
          "option": {
            "$not": {
              "$elemMatch": { "weight": "40", "size": "40" }
            }
          }
        },
        "update": {
          "$push": { "option": { "weight": "40", "size": "40",  "price": "300" } }
        }
      }},
      { "updateOne": {
        "filter": { "_id": 1 },
        "update": {
          "$setOnInsert": {
            "option": [
               { "weight": "40", "size": "40",  "price": "300" }
             ]
          }
        },
        "upsert": true
      }}
    ])
    
    不管怎样,只要找到一个与提供的条件不匹配的,就可以创建新的数组元素

  • 仅在未找到主文档
    \u id
    的情况下尝试“向上插入”,并使用,以便在找到文档时此操作不会执行任何操作


  • 与以前一样,尽管整个批处理都被发送到服务器,但实际上只有其中一个会写入任何内容。

    您可能可以通过一个仅限mongodb的操作将内容连接在一起,您最好添加一个“版本”字段并使用乐观锁定,就像java+spring数据为您所做的那样(google for@version)。这将允许在持久化之前对整个对象进行复杂的更改和验证。

    您的意思肯定是“所有”数组项同时具有“权重”和“大小”。在您的快速复制/粘贴中,您没有显示。是的,我错了,我编辑了它。它实际上执行3个操作,而不是1个。@AgostonHorvath是的。但这只是一个请求。你不能在一次操作中完成这项工作,而读取整个文档并将其写回是完全错误的,原因有很多。当你有如此复杂的文档,然后请求在其中进行深入更改时,对我来说,这是一个危险信号,表明你的实际需求是复杂的更新和验证。在mongo中你无法做到这一点,即使你做到了(就像你在回答中建议的那样),以后维护/更改它也是一件痛苦的事情。通过在代码中进行更改和验证,您可以用更少、更容易理解的代码实现更好的控制和灵活性,并有更好的测试可能性。如果重量和大小都超过matching@naruto这是第一个条件,与问题中的数据完全匹配。检查您正在运行的数据,或者更好的做法是实际运行您在问题中提供的数据。与上一个问题唯一不同的是
    $elemMatch
    。阅读链接文档并理解它是用来匹配“多个条件”的,就像我告诉你的那样。
    db.collection.bulkWrite([
      { "updateOne": {
        "filter": { 
          "_id": "1", 
          "option": { 
            "$elemMatch": { "weight": "40", "size": "40" }
          }
        },
        "update": { 
          "$set": { "option.$.price": "300" }
        }
      }},
      { "updateOne": {
        "filter": {
          "_id": "1",
          "option": {
            "$not": {
              "$elemMatch": { "weight": "40", "size": "40" }
            }
          }
        },
        "update": {
          "$push": { "option": { "weight": "40", "size": "40",  "price": "300" } }
        }
      }},
      { "updateOne": {
        "filter": { "_id": 1 },
        "update": {
          "$setOnInsert": {
            "option": [
               { "weight": "40", "size": "40",  "price": "300" }
             ]
          }
        },
        "upsert": true
      }}
    ])
    
     "$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }