我有这种类型的文件:
{
"_id":ObjectId("527cedf19df815000700123b"),
"title":"title question",
"content": "content question",
"answer": [
{
"_id": ObjectId("527cee379df8155c1300002a"),
"content": "<p>answer 1<\/p>",
"total_dislike": NumberInt(10),
"total_like": NumberInt(20)
},
{
"_id": ObjectId("527d135b9df8152c04005ddd"),
"content": "<p>answer 2<\/p>",
"total_dislike": NumberInt(2),
"total_like": NumberInt(6)
}
]
}
我想创建一个answer.total_dislike > answer.total_like
。
我使用了这个查询:
> db.Question.find( { $where: "this.answer.total_dislike > this.answer.total_like" } );
但它不起作用。如何编写查询以返回answer.total_dislike
大于answer.total_like
的所有子文档?
答案 0 :(得分:1)
$where
运算符不会像你想的那样深入研究子文档数组。您将需要首先使用不同的运算符。我不确定这是否有效,但你可以尝试这个或它的变体:
db.Question.find(
{ answer:
{ $elemMatch:
{ $where: "this.total_dislike > this.total_like"
}
}
}
);
答案 1 :(得分:1)
由于此查询执行效果不佳(无法使用索引,并且必须针对集合中的每个文档运行),我建议您尽可能预先计算条件的结果并将其存储为新字段。虽然它稍微增加了文档结构的大小,但它会使查询超快,特别是如果字段被索引:
"answer": [
{
"_id": ObjectId("527cee379df8155c1300002a"),
"content": "<p>answer 1<\/p>",
"total_dislike": NumberInt(10),
"total_like": NumberInt(20),
"likes_more": Boolean(true)
},
然后:
db.Question.find(
{ answer:
{ $elemMatch:
{ likes_more: false }
}
}
);
使用NoSQL数据库时,有时您需要稍微考虑一下这个问题。
另一种选择是执行MapReduce,定期更新以反映新的Like / Dislike更改。虽然根据您当前的结构它并不完全相同,但您可以进行相同类型的计算。
答案 2 :(得分:0)
为什么不使用聚合框架?
db.Question.aggregate(
{$unwind:"$answer"},
{$project:{disliked:{$cond:[{$gt:[{"$answer.total_dislike","$answer.total_like"}], true, false]},
title:1}
},
{$match:{disliked:true}}
)