对你来说这可能听起来像是一个简单的问题,但我花了3个多小时来实现它,但我在中途陷入困境。
输入:
问题陈述:我需要从数据库中找到满足以下条件的所有文件:
查询:我如何达到要求#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
}
}
];
答案 0 :(得分:4)
您的尝试似乎很接近,但当然您需要实施一些事情来匹配您的逻辑"为了获得最终的分数"你想要的价值。
只需稍微改变您的投影逻辑,并假设两个"关键字"和"标签"是文档中的数组:
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
值以便与" set"进行比较。你想要的解决方案。
$add
运算符提供额外的"权重"对你想要的成员"体重"你的回答。