如何对文档进行加权以创建排序条件



我正在尝试聚合一个集合,其中有如下文档:

[
{  
"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运算符不是布尔运算符,因此它不起作用。我环顾四周,没有找到任何能帮我的接线员。

正如您所说,您需要一个逻辑运算符来计算$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 ]}
}
}}
])

我将把其余的实现留给您,但这应该显示出您想要进行匹配的基本构造

添加

从您的评论来看,似乎还有一个您正在努力解决的编程问题,与您如何执行这样的聚合有关,其中您有一个Array项目以上面给出的形式进行查询:

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 ]}
}
}}
])

或者就这一点而言,你需要构建的任何部分。在现实世界中,我们通常是这样做的,在那里我们几乎永远不会硬编码这样的数据结构。

最新更新