我正在尝试聚合一个集合,其中有一些文档看起来像这样:
[
{
"title" : 1984,
"tags" : ['dystopia', apocalypse', 'future',....]
},
....
]
我有一个关键字的标准数组,例如:
var keywords = ['future', 'google', 'cat',....]
我想要实现的是聚合集合以便根据“便利”标准对其进行分组,以便按照标签字段中包含更多关键字的文档对文档进行排序。
这意味着,如果一个文档在其标签中包含:'future','google','cat',它将在另一个包含'future','cat','apple'之前排序。
到目前为止,我尝试过这样的事情:
db.books.aggregate(
{ $group : { _id : {title:"$title"} , convenience: { $sum: { $cond: [ {tags: {$in: keywords}}, 1, 0 ] } } } },
{ $sort : {'convenience': -1}})
但是$in
运算符不是布尔值,所以它不起作用。我环顾四周,找不到任何可以帮助我的操作员。
答案 0 :(得分:1)
正如您所说,您需要一个逻辑运算符来评估$cond。这有点简洁,但这是使用$or的实现:
db.books.aggregate([
{$unwind: "$tags" },
{$group: {
_id: "$title",
weight: {
$sum: {$cond: [
// Test *equality* of the `tags` value against any of the list
{$or: [
{$eq: ["$tags", "future"]},
{$eq: ["$tags", "google"]},
{$eq: ["$tags", "cat"]},
]},
1, 0 ]}
}
}}
])
我将把剩下的实现留给你,但这应该显示你想要做的匹配点的基本结构。
根据您的评论,似乎还有一个您正在努力解决的编程问题,与您如何执行这样的聚合相关,您可以使用上面提供的表单中的数组项进行查询:
var keywords = ['future', 'google', 'cat',....]
由于此结构不能直接用于管道条件,您需要做的是将转换为您需要的内容。每种语言都有自己的方法,但在JavaScript版本中:
var keywords = ['future', 'google', 'cat'];
var orCondition = [];
keywords.forEach(function(value) {
var doc = {$eq: [ "$tags", value ]};
orCondition.push(doc);
});
然后只需定义orCondition
变量的聚合查询:
db.books.aggregate([
{$unwind: "$tags" },
{$group: {
_id: "$title",
weight: {
$sum: {$cond: [
{$or: orCondition }
1, 0 ]}
}
}}
])
或者就此而言,您需要构建的任何部分。这通常是在现实世界中如何完成的,我们几乎从不硬编码像这样的数据结构。