删除 pyMongo 列表中的列表条目

Removing a list entry in a list in pyMongo

我有一个数据库集合,其中包含如下对象:

{
    "_id": ObjectId("something"),
    "name_lower": "total",
    "name": "Total",
    "mounts": [
        [
            "mount1",
            "instance1"
        ],
        [
            "mount2",
            "instance1"
        ],
        [
            "mount1",
            "instance2"
        ],
        [
            "mount2",
            "instance2"
        ]
    ]
}

假设我想删除所有具有实例 instance2 的挂载,我将如何做?我找了好久

你可以这样做

[
  {
    $unwind: "$mounts"
  },
  {
    $match: {
      "mounts": {
        $ne: "instance2"
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      name: {
        $first: "$name"
      },
      mounts: {
        $push: "$mounts"
      }
    }
  }
]

工作Mongo playground

这个答案是基于@varman 的答案,但更像 pythonic 和高效。

第一阶段应该是$match条件,过滤掉不需要更新的文档。

由于mounts键是由一个嵌套数组组成的,我们必须$unwind它,这样我们才能删除需要删除的数组元素。

我们必须再次应用 $match 条件以过滤掉必须删除的元素。

最后,我们必须通过_id$group管道,这样在前一阶段得到$unwind的文档将被分组为一个文档。

from pymongo import MongoClient


client = MongoClient("<URI-String>")
col = client["<DB-Name"]["<Collection-Name>"]


count = 0
for cursor in col.aggregate([
{
        "$match": {
            "mounts": {"$ne": "instance2"}
        }
    },
    {
        "$unwind": "$mounts"
    },
    {
        "$match": {
            "mounts": {"$ne": "instance2"}
        }
    },
    {
        "$group": {
            "_id": "$_id",
            "newMounts": {
                "$push": "$mounts"
            }
        }
    },
]):
    # print(cursor)
    col.update_one({
        "_id": cursor["_id"]
    }, {
        "$set": {
            "mounts": cursor["newMounts"]
        }
    })

    count += 1
    print("\r", count, end="")

print("\n\nDone!!!")