我们目前有一个查询电影收藏,以便返回'汇编'与用户生成的编辑相匹配的文档'。
用户可以应用一些过滤器:受众群体,提供商和格式。
目前,此find()组合会返回以下文档,即使匹配的'标题为'不适合过滤器,而是编译中的第二部电影'匹配过滤器..
{
"_id": "551781485d9d35e4720c9057",
"name": "Consciousness",
"audience": {
"adults": true,
"teenagers": true,
"kids": false
},
"compilation": [
{
"title": "2001",
"_id": "551781485d9d35e4720c9059",
"provider": {
"amazon": false,
"apple": true,
"hulu": false,
"google": true,
"xfinity": false
},
"format": {
"hd": false,
"sd": false,
"4k": true
}
},
{
"title": "Matrix",
"_id": "551781485d9d35e4720c9059",
"provider": {
"amazon": false,
"apple": true,
"hulu": false,
"google": true,
"xfinity": false
},
"format": {
"hd": true,
"sd": false,
"4k": false
}
}
]
}
如何重写,以便$或+ $和查询专门与$ elemMatch相关? 适用于'汇编'有一部电影,但没有多部电影..
Models.Movies.find(
{
"collection": {
"$elemMatch": {
"title": "2001"
}
}
}
)
.and([
{$or : audienceQuery},
{$or : providerQuery}
])
.and(formatQuery)
过滤查询的位置如下:
audienceQuery == {"audience.adults":true}, {"audience.teenagers":true}, {"audience.kids":false};
providerQuery == {"compilation.provider.apple":true}, {"compilation.provider.google":true};
formatQuery == {"compilation.format.hd":true};
答案 0 :(得分:1)
考虑使用 aggregation framework ,您可以在管道阶段开始时利用$match
操作进行早期过滤,以限制进入管道的文档。放置在管道的开头时, $match
操作使用合适的索引来仅扫描集合中的匹配文档。您的第二个管道阶段将涉及在compilation
数组上使用 $unwind
操作,以便后续应用 $match
操作将过滤解构数组:剩余的管道操作$group
和$project
然后传递分组文档,只包含先前过滤的输入文档和新计算字段中的指定字段:
因此,您的聚合管道将如下所示:
Models.Movies.aggregate([
{
"$match": {
"compilation.title": "2001",
"$and": [
{ "$or": [{"audience.adults": true}, {"audience.teenagers": true}, {"audience.kids": false}] },
{ "$or": [{"compilation.provider.apple": true}, {"compilation.provider.google": true}] }
],
"compilation.format.hd": true
}
},
{
"$unwind": "$compilation"
},
{
"$match": {
"compilation.title": "2001",
"$and": [
{ "$or": [{"audience.adults": true}, {"audience.teenagers": true}, {"audience.kids": false}] },
{ "$or": [{"compilation.provider.apple": true}, {"compilation.provider.google": true}] }
],
"compilation.format.hd": true
}
},
{
"$group": {
"_id": {
"_id": "$_id",
"name": "$name",
"audience": "$audience"
},
"compilation": {
"$push": "$compilation"
}
}
},
{
"$project": {
"_id": "$_id._id",
"name": "$_id.name",
"audience": "$_id.audience",
"compilation": 1
}
}
])
结果:
/* 0 */
{
"result" : [
{
"_id" : "551781485d9d35e4720c9057",
"compilation" : [
{
"title" : "2001",
"_id" : "551781485d9d35e4720c9059",
"provider" : {
"amazon" : false,
"apple" : true,
"hulu" : false,
"google" : true,
"xfinity" : false
},
"format" : {
"hd" : true,
"sd" : false,
"4k" : true
}
}
],
"name" : "Consciousness",
"audience" : {
"adults" : true,
"teenagers" : true,
"kids" : false
}
}
],
"ok" : 1
}