用过滤器查询子文档数组并用猫鼬返回原始文档

时间:2019-09-25 17:00:59

标签: node.js mongodb express mongoose

我正在使用猫鼬,并具有以下结构的文档:

{
  user: {
    comments: [
      { title: "mpla", active: true },
      { title: "mpla", active: false }
    ]
  }
}
...

如何返回我的所有文档,但只能返回注释数组中的活动注释。

2 个答案:

答案 0 :(得分:1)

您将必须使用mongodb聚合,因此查询将为:

db.collectionName.aggregate(
 {
   $unwind:  $user.comments
 }
) 

这将解构comment数组,并将包括其他字段,例如每个文档中包含的id。例如,假设您的文档是:

{ "_id": 1, "user" : 
   { "comments": 
     [ { "title": "mpla", "active" : true }, { "title": "mpla", "active" : false }  }]
    }
}

运行上面给出的查询后,将得到以下文档:

{ "_id": 1, "user" : 
   { "comments": { "title": "mpla", "active" : true }  
   }
 }
}

{ "_id": 1, "user" : 
   { "comments": { "title": "mpla", "active" : false }   
   }
 }
}

您现在可以看到,我们有两个单独的文档,您现在可以使用$ match运算符查询它们,并使用$ group运算符将它们重新组合成一个数组。 希望能回答您的问题。

答案 1 :(得分:1)

在这里以一般情况为例,其中主要文档可能具有除 user 以外的其他字段,而用户文档本身可能还有其他字段:

示例文档:

[
  {
    user: {
      comments: [
        { title: "mpla", active: true },
        { title: "mpla", active: false }
      ],
      name: "abc",
      gender: "male",
      createdDate: new Date("2019-04-01"),
      modifiedDate: new Date("2019-08-24")
    },
    story: {
      name: "a mocking bird",
      year: 1994,
      cost: "$5"
    }
  },
  {
    user: {
      comments: [
        { title: "nope", active: true },
        { title: "hello", active: true }
      ],
      name: "pqr",
      gender: "female",
      createdDate: new Date("2019-05-01"),
      modifiedDate: new Date("2019-09-24")
    },
    story: {
      name: "a kite runner",
      year: 2005,
      cost: "$2"
    }
  }
]

现在,必须返回所有包含文档的字段,但注释数组应仅包含 active=true 个文档。

具有$filter$project的聚合查询:

db.collection.aggregate([
  {
    $project: {
      _id: 1,
      story: 1,
      user: {
        name: 1,
        gender: 1,
        createdDate: 1,
        modifiedDate: 1,
        comments: {
          $filter: {
            input: "$user.comments",
            as: "comment",
            cond: { $eq: ["$$comment.active", true] }
          }
        }
      }
    }
  }
]).pretty();

输出文档:

{
    "_id" : ObjectId("5d8bb8c66926e92a334275d4"),
    "user" : {
        "name" : "abc",
        "gender" : "male",
        "createdDate" : ISODate("2019-04-01T00:00:00Z"),
        "modifiedDate" : ISODate("2019-08-24T00:00:00Z"),
        "comments" : [
            {
                "title" : "mpla",
                "active" : true
            }
        ]
    },
    "story" : {
        "name" : "a mocking bird",
        "year" : 1994,
        "cost" : "$5"
    }
},
{
    "_id" : ObjectId("5d8bb8c66926e92a334275d5"),
    "user" : {
        "name" : "pqr",
        "gender" : "female",
        "createdDate" : ISODate("2019-05-01T00:00:00Z"),
        "modifiedDate" : ISODate("2019-09-24T00:00:00Z"),
        "comments" : [
            {
                "title" : "nope",
                "active" : true
            },
            {
                "title" : "hello",
                "active" : true
            }
        ]
    },
    "story" : {
        "name" : "a kite runner",
        "year" : 2005,
        "cost" : "$2"
    }
}