我有一个包含这样文件的集合:
{
"_id" : ObjectId("59df91dae4b03289d79efb4e"),
"name" : "TEST",
"payload" : [
{
"_id" : "ABC",
"status": "FALSE"
},
{
"_id":"DEF",
"status": "TRUE"
},
{
"_id" : "XYZ",
"status": "NULL"
}
]
}
我正在尝试查找状态为TRUE / FALSE的所有payload._id。 预期结果是
["ABC","DEF"]
到目前为止,我有类似的东西。
db.collection.distinct('payload._id',{"_id" : "TEST"})
不确定如何为数组中的元素添加条件。
答案 0 :(得分:2)
.distinct()
的查询条件适用于"文档选择"而不是包含的数组条目"在"该文件。如果您需要"过滤"数组内容然后你应用.aggregate()
代替,以及一点点后期处理,只获得"值"在数组响应中。
db.collection.aggregate([
{ "$match": { "_id": "TEST" } },
{ "$unwind": "$payload" },
{ "$match": { "payload.status": { "$in": ["TRUE","FALSE"] } } },
{ "$group": { "_id": "$payload._id" } },
]).map( d => d._id );
主要部分是$unwind
管道阶段,主要是因为您希望数组中的值稍后用作$group
的关键字。这实质上为每个数组成员生成一个新文档,但每个文档只包含该数组成员。它正常化"非正规化"对于包含数组的MongoDB结构。
接下来就是以下$match
管道,它与任何查询一样,只选择符合条件的文档。由于所有阵列成员现在都是"文件"然后排除非匹配条目(作为文档)。你可以选择使用$filter
来提取数组,但由于我们需要$unwind
用于下一阶段,我们也可以简单地$match
。
此时,您只剩下符合条件的数组条目。 $group
是获得" distinct"因此,通常您可以在更广泛的选择范围内执行此操作,而不仅仅是单个文档或此处值尚未区分的任何内容。所以这只是保持.distinct()
完全相同的行为。
最后,由于.aggregate()
的输出与.distinct()
的设计不同,因为它返回"文件"在结果中,我们只使用.map()
方法处理游标结果并仅返回"值"从特定的文档属性作为"数组"。
答案 1 :(得分:1)
我正在尝试查找状态为TRUE / FALSE
的所有payload._id
您要运行的查询是:
db.collection.distinct('payload._id', {
'payload.status': { $in: ["TRUE", "FALSE"] }
})
更简洁的方法是:
db.collection.distinct('payload._id', {
$or: [
{'payload.status': "TRUE" },
{'payload.status': "FALSE" }
]
})