arrays - 如何使用 MongoDB 从嵌套在另一个数组中的数组中删除元素

标签 arrays mongodb

问题

假设我有一个文档如下:

doc = {
"_id" : ObjectId("56464c726879571b1dcbac79"),
"food" : {
    "fruit" : [
        "apple",
        "orange"
    ]
},
"items" : [
    {
        "item_id" : 750,
        "locations" : [
            {
                "store#" : 13,
                "num_employees" : 138
            },
            {
                "store#" : 49,
                "num_employees" : 343
            }
        ]
    },
    {
        "item_id" : 650,
        "locations" : [
            {
                "store#" : 12,
                "num_employees" : 22
            },
            {
                "store#" : 15,
                "num_employees" : 52
            }
        ]
    }
]
}


我要删除元素

    {'#store#' : 12, 'num_employees' : 22} 

仅当以下条件为真时:

  • food.fruit 包含值 appleorange
  • item_id 的 ID 650



我尝试的解决方案

我尝试了以下方法:

     db.test.update({"food.fruit" : {"$in" : ["apple", "orange"]}, "items.item_id":650},{$pull:{'items.$.locations':{'store#':12,'num_employees':22}}})


更新不起作用。有趣的是,如果删除查询的 $in 运算符部分,它就可以工作。我正在使用 MongoDB v3.0.6 并查阅了 MongoDB 手册以了解 $(update) 的使用:

https://docs.mongodb.org/manual/reference/operator/update/positional/

文档包含一段有趣的内容:

  Nested Arrays
  The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value

当然,我的查询遍历了不止一个数组。事实上,如果我从查询中删除 'food.fruit' : {$in : ['apple']} ,它就可以工作。然而,这确实 不能解决我的问题,因为我当然需要那个查询。我正在寻找一个最好的解决方案:

  • 不需要架构更改
  • 在一个查询/更新语句中执行

最佳答案

如果您需要在 "food.fruit" 中匹配多个可能的值,因此需要匹配多个可能的文档(这是唯一有意义的情况),那么您可以随时替换您的 $in$where 中的 JavScript 逻辑:

db.test.update(
    {
        "items.item_id": 650,
        "$where": function() {
            return this.food.fruit.some(function(el) {
                return ["apple","orange"].indexOf(el) != -1;
            });
        }
    },
    { "$pull": { "items.$.locations": { "store#": 12 } } },
    { "multi": true }
)

这基本上应用了相同的测试,虽然不如 “food.fruit” 有效,但值不能在索引中测试,但希望 “items.item_id”是一个足够的匹配,至少不会使这成为一个真正的问题。

另一方面,针对 MongoDB 服务器版本 3.1.9(开发系列)进行测试,以下工作没有问题:

db.test.update(
    { "food.fruit": { "$in": ["orange","apple"] }, "items.item_id": 650 },
    { "$pull": { "items.$.locations": { "store#": 12 } } },
    { "multi": true }
)

我还建议,如果您打算在查询中包含 _id,那么无论如何您都只会匹配一个文档,因此您只需要在您希望的数组上提供匹配项至 $pull来自:

db.test.update(
    { "_id": 123, "items.item_id": 650 },
    { "$pull": { "items.$.locations": { "store#": 12 } } }
)

这相当简单并且没有冲突,除非您确实需要确保所需的"food.fruits" 值实际存在以便应用更新。在这种情况下,请按照前面的示例进行操作。

关于arrays - 如何使用 MongoDB 从嵌套在另一个数组中的数组中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33701123/

相关文章:

mongodb - 连接到不同命名空间中的 Kubernetes mongo db

mysql - 将数据库结构从 MySQL 迁移到 MongoDB

mongodb - 一旦删除并重新创建索引,Elasticsearch不会自动提取现有的mongoDB数据

node.js - Nodejs 中的 Mongodb 与 Postgres

c - 通过简单地使用指向它中间的指针来拆分 C 数组是否是一种不好的做法?

java - 如何将选定的项目从一个数组复制到另一个数组?

php - MongoDB 按平均组合数或嵌套子数组排序

javascript - _.initial 和 _.dropRight 有什么区别?

python - 如何从数组中删除数据,然后在 python 中插入该间隙?

c++ - 调用另一个函数的函数会给出错误的输出 C++?