展开对象数组 mongoDB

Cru*_*lIO 3 regex mongodb mongodb-query aggregation-framework

我的收藏包含以下两个文件

{
      "BornYear": 2000,
      "Type": "Zebra",
      "Owners": [
        {
          "Name": "James Bond",
          "Phone": "007"
        }
      ]
    }

    {
      "BornYear": 2012,
      "Type": "Dog",
      "Owners": [
        {
          "Name": "James Brown",
          "Phone": "123"
        },
        {
          "Name": "Sarah Frater",
          "Phone": "345"
        }
      ]
    }
Run Code Online (Sandbox Code Playgroud)

我想找到所有有主人叫詹姆斯的动物。我尝试展开 Owners 数组,但无法访问 Name 变量。

Nei*_*unn 5

这里有点用词不当。要在“集合”中找到“对象”或项目,那么您真正需要做的就是匹配“对象/项目”

db.collection.find({
    "Owners.Name": /^James/
})
Run Code Online (Sandbox Code Playgroud)

哪个有效,但当然不会将结果限制为“詹姆斯”的“第一次”匹配,这将是:

db.collection.find(
    { "Owners.Name": /^James/ },
    { "Owners.$": 1 }
)
Run Code Online (Sandbox Code Playgroud)

作为基本投影。但这只是一个“单一”匹配,这意味着您需要.aggregate()像这样的方法:

db.collection.aggregate([
    // Match the document
    { "$match": {
        "Owners.Name": /^James/
    }},

    // Flatten  or de-normalize the array
    { "$unwind": "Owners" },


    // Filter th content
    { "$match": {
        "Owners.Name": /^James/
    }},

    // Maybe group it back
    { "$group": {
        "_id": "$_id",
        "BornYear": { "$first": "$BornYear" },
        "Type": { "$first": "$Type" },
        "Ownners": { "$push": "$Owners" }
    }}
])
Run Code Online (Sandbox Code Playgroud)

这允许在过滤时在子文档数组中进行多个匹配。

另一点是正则表达式上的“锚点”或“^”插入符号。您确实需要它,以便在可以正确使用索引的字符串的“开始”处进行匹配。开放式正则表达式操作不能使用索引。