这对你来说可能是一个简单的问题,但我花了3个多小时才完成,但中途遇到了麻烦。
输入:
- 关键字列表
- 标签列表
问题声明:我需要从数据库中找到满足以下条件的所有文档:
- 列出具有1个或多个匹配关键字的文档。(已实现)
- 列出具有1个或多个匹配标记的文档。(已实现)
- 根据权重对找到的文档进行排序:每个关键字匹配得2分,每个标签匹配得1分
查询:我如何才能实现需求#3。
我的尝试:在我的尝试中,我只能根据关键字匹配列出(也不需要将权重乘以2)。
标签是文档的数组。每个标签的结构类似
{
"id" : "ICC",
"some Other Key" : "some Other value"
}
关键字是字符串数组:
["women", "cricket"]
查询:
var predicate = [
{
"$match": {
"$or": [
{
"keywords" : {
"$in" : ["cricket", "women"]
}
},
{
"tags.id" : {
"$in" : ["ICC"]
}
}
]
}
},
{
"$project": {
"title":1,
"_id": 0,
"keywords": 1,
"weight" : {
"$size": {
"$setIntersection" : [
"$keywords" , ["cricket","women"]
]
}
},
"tags.id": 1
}
},
{
"$sort": {
"weight": -1
}
}
];
您的尝试似乎很接近,但当然您需要实现一些"匹配您的逻辑"的东西,才能获得您想要的最终"分数"值。
这只是一个稍微改变投影逻辑的问题,并假设"关键字"one_answers"标签"都是文档中的数组:
db.collection.aggregate([
// Match your required documents
{ "$match": {
"$or": [
{
"keywords" : {
"$in" : ["cricket", "women"]
}
},
{
"tags.id" : {
"$in" : ["ICC"]
}
}
]
}},
// Inspect elements and create a "weight"
{ "$project": {
"title": 1,
"keywords": 1,
"tags": 1,
"weight": {
"$add": [
{ "$multiply": [
{"$size": {
"$setIntersection": [
"$keywords",
[ "cricket", "women" ]
]
}}
,2] },
{ "$size": {
"$setIntersection": [
{ "$map": {
"input": "$tags",
"as": "t",
"in": "$$t.id"
}},
["ICC"]
]
}}
]
}
}},
// Then sort by that "weight"
{ "$sort": { "weight": -1 } }
])
因此,这里的$map
逻辑基本上"转换"另一个数组,只给出id
值,以便与您想要的"设置"解决方案进行比较。
$add
运算符为您想要"加权"响应的成员提供额外的"权重"。