switch将分数添加到MongoDB聚合中

switch将分数添加到MongoDB聚合中

本文介绍了使用$ switch将分数添加到MongoDB聚合中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据 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聚合中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 20:44