问题描述
我正在尝试根据 name
字段匹配的值向我的mongodb聚合中添加一个分数。
I'm trying to add a score to my mongodb aggregation, based on which value the name
field matched on.
例如:如果名称
完全匹配 sitt,则分数为100。
如果名称
匹配/ sitt / i,得分为50。
For example: if the name
matches "sitt" exactly, the score is 100.If the name
matches /sitt/i, the score is 50.
这是我的代码:
db.getCollection('tags').aggregate([
{
"$match": {
"$or": [
{
"name": "sitt"
},
{
"name": /sitt/i
},
{
"name": /^sitt/i
}
]
}
},
{
"$project": {
"name": 1,
"score": {
"$switch": {
"branches": [
{
"case": {"name": "sitt"},
"then": 100
},
{
"case": {"name": /sitt/i},
"then": 50
}
],
"default": 0
}
}
}
}
])
但是分数
始终为100。该语句始终为真。
But the score
always turns out to be 100. The statement is always true.
也许$ switch只是用于数字值吗?
Are $switch cases only meant to be used on numerical values, perhaps?
推荐答案
聚合框架 $ switch
大小写表达式必须有效。这些表达式是在聚合管道中求值的,与查询中使用的 $ match
语法不同。 MongoDB 3.4对于正则表达式没有,所以你必须要有创造力。
Aggregation framework $switch
case expressions have to be valid aggregation expressions that resolve to a boolean value. These expressions are evaluated within the aggregation pipeline and are different from the $match
syntax used in queries. MongoDB 3.4 doesn't have a string expression for regular expressions, so you have to be a bit creative.
设置一些测试数据:
db.tags.insert([{name:"sitt"},{name:"siTt"},{name:"babysiTt"},{name:"sitter"}])
使用与原始比较等效的聚合表达式:
Using aggregation expressions equivalent to your original comparisons:
db.tags.aggregate([
// Match candidates (note: an unanchored case-insensitive regex cannot use index effectively
{ "$match": {
"name": /sitt/i,
}},
{ "$project": {
"_id" : 0,
"name" : 1,
"score": {
"$switch": {
"branches": [
// First, check for exact match
{
"case": {$eq: ["$name", "sitt"] },
"then": 100
},
// Next, case-insensitive anchored substring
// (since the following comparison would match this as well)
{
"case": {$eq: [{ $toLower: {$substrBytes: ["$name", 0, 4]}}, "sitt"]},
"then": 50
},
// Finally, case-insensitive substring match
{
"case": {$indexOfCP: [{ $toLower:"$name"}, "sitt"]},
"then": 25
}
],
"default": 0
}
}
}},
// Sort in descending order of relevance
{ $sort: { score: -1 } }
])
结果为:
{
"result": [
{
"name": "sitt",
"score": 100
},
{
"name": "siTt",
"score": 50
},
{
"name": "sitter",
"score": 50
},
{
"name": "babysiTt",
"score": 25
}
],
"ok": 1
}
注意:支持&在MongoDB问题跟踪器中观看如果您希望看到此功能的添加。
Note: upvote & watch SERVER-11947: Add a regex expression to the aggregation language in the MongoDB issue tracker if you are keen to see this feature added.
这篇关于使用$ switch将分数添加到MongoDB聚合中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!