0

我有一个families收藏。其中的文档有一个users数组。鉴于这份家庭文件:

{
    "id" : "1",
    "users" : [ 
        {
            "id" : "2",
            "identities" : [ 
                {
                    "type" : "email",
                    "email" : "foo"
                }, 
                {
                    "type" : "email",
                    "email" : "bar"
                }
            ]
        }, 
        {
            "id" : "3",
            "identities" : [ 
                {
                    "type" : "email",
                    "email" : "baz"
                }, 
                {
                    "type" : "email",
                    "email" : "qux"
                }
            ]
        }
    ]
}

我想投影数组元素的type字段identities,但仅限于我正在查询的特定用户。位置运算符获得正确的用户:

db.families.findOne(
    { 'users.id': '2' },
    { 'users.$': 1 } 
  )

我可以指定我感兴趣的领域:

db.families.findOne(
    { 'users.id': '2' },
    { 'users.identities.type': 1 } 
  )

但是当两者结合时,只有位置运算符受到尊重:

db.families.findOne(
    { 'users.id': '2' },
    { 'users.$': 1, 'users.identities.type': 1 } 
  )

(返回 id 为 2 的用户,但返回所有字段的标识数组元素)。想过尝试这个:

db.families.findOne(
    { 'users.id': '2' },
    { 'users.$.identities.type': 1 } 
  )

但这并不好,因为根据文档

MongoDB 忽略 $ 之后的路径部分

有没有办法做到这一点?

4

2 回答 2

0

您只需使用 $ 运算符来投影字段。

询问:

db.collection.find({
  "users.id": "2"
},
{
  "users.identities.type.$": 1
});

结果:

[
  {
    "_id": "1",
    "users": [
      {
        "identities": [
          {
            "type": "email"
          },
          {
            "type": "email"
          }
        ]
      }
    ]
  }
]
于 2021-02-06T22:43:41.910 回答
0

这将仅投影所选 users.id 的类型和 users.id:

 db.families.findOne({"users.id":"2"},{"users":{id:1,"identities.type.$":1}})

 {
"_id" : ObjectId("601f1974cf95940e8e0c814e"),
"users" : [
    {
        "id" : "2",
        "identities" : [
            {
                "type" : "email"
            },
            {
                "type" : "email"
            }
        ]
    }
]
}

(在 mongod 4.4.3 中测试)也可以这样重写(也是 4.4.3):

 db.families.findOne({"users.id":"2"},{"users":{id:1,"identities":{"type.$":1}}})

通过以下聚合可以实现 mongod 4.2.12 中的相同结果:

 db.families.aggregate([  
{$project:{users:{$filter:{input:"$users",as:"us",cond:{$eq:["$$us.id","2"]}}}}}  , 
{$project:{"users.identities.type":1 , "users.id":1  }}     
 ])

聚合解释:

  • 在第一个 $project 阶段,您过滤 users.id:2 的数组元素
  • 在第二个 $project 阶段,您只投影您需要的字段
于 2021-02-06T22:43:45.183 回答