如何为 MongoDb 中搜索到的文档分配权重?
How to assign weights to searched documents in MongoDb?
这对你来说听起来像是一个简单的问题,但我花了 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
}
}
];
您的尝试似乎很接近,但当然您需要对 "match your logic" 实施一些操作才能获得您想要的最终 "score" 值。
只需稍微改变一下投影逻辑,并假设 "keywords" 和 "tags" 都是文档中的数组:
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
逻辑是基本的,"transforms" 另一个数组只给出 id
值以与您想要的 "set" 解决方案进行比较。
$add
运算符向您希望 "weight" 您的回复的成员提供额外的 "weight"。
这对你来说听起来像是一个简单的问题,但我花了 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
}
}
];
您的尝试似乎很接近,但当然您需要对 "match your logic" 实施一些操作才能获得您想要的最终 "score" 值。
只需稍微改变一下投影逻辑,并假设 "keywords" 和 "tags" 都是文档中的数组:
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
逻辑是基本的,"transforms" 另一个数组只给出 id
值以与您想要的 "set" 解决方案进行比较。
$add
运算符向您希望 "weight" 您的回复的成员提供额外的 "weight"。