【问题标题】:How can I apply filters in elasticsearch NEST functionscore function如何在弹性搜索 NEST 函数中应用过滤器核心函数
【发布时间】:2020-12-10 09:22:22
【问题描述】:

为了根据字段值控制文档的分数,我在我的 DSL 查询中使用了带有 function_score 的过滤器,这会得到我期望的结果。

但是在 NEST 中实现这一点,结果是不同的;分数不适用于过滤器值。通过进一步调查,我发现 ScoreFunctionsDescriptor 不支持某些版本的 C# NEST 过滤器。还是这样吗? 您能否提供一个使用 NEST 实现此功能的工作选项? (我是 Elastic Search 和 C# 的新手,所以如果这是一个菜鸟问题,请原谅)。

我目前使用的是 Elasticsearch v7.6 和 NEST v7.5.1。

谢谢!

DSL 查询

GET /help/_search
{
  "query":{
   "function_score": {
     "query": {
     "bool": {
      "must": [
        {
          "multi_match": {
            "query": "AGC",
            "fields": [
              "title^2",
              "description^1"
            ],
            "type":"most_fields",
            "fuzziness": "AUTO:4,8",
            "prefix_length": 2,
            "boost": 5            
          }
        }
        ]
  }
  },
**  "functions": [
   { 
    "filter": {
     "term":{
       "product":"A"
            }
              },
        "weight": 45
    },
   { 
    "filter": {
     "term":{
       "product":"B"
            }
              },
        "weight": 20
    },
   { 
    "filter": {
     "term":{
       "product":"C"
            }
              },
        "weight": 10
    }
       ],**
    "score_mode": "max",
    "boost_mode": "multiply"    
}
}
}```

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    通过进一步调查,我发现 ScoreFunctionsDescriptor 不支持某些版本的 C# NEST 过滤器。还是这样吗?

    The function you're looking for is a weight function 应用了过滤器。这已在客户端中支持 很长时间。

    客户端相当于

    var response = client.Search<object>(s => s
        .Query(q => q
            .FunctionScore(fs => fs
                .Query(fsq => fsq
                    .Bool(b => b
                        .Must(mu => mu
                            .MultiMatch(mm => mm
                                .Query("AGC")
                                .Fields(new[] { "title^2", "description^1" })
                                .Type(TextQueryType.MostFields)
                                .Fuzziness(Fuzziness.AutoLength(4,8))
                                .PrefixLength(2)
                                .Boost(5)
                            )
                        )
                    )
                )
                .Functions(fu => fu
                    .Weight(w => w
                        .Filter(f => f
                            .Term("product", "A")
                        )
                        .Weight(45)
                    )
                    .Weight(w => w
                        .Filter(f => f
                            .Term("product", "B")
                        )
                        .Weight(20)
                    )
                    .Weight(w => w
                        .Filter(f => f
                            .Term("product", "C")
                        )
                        .Weight(10)
                    )
                )
                .ScoreMode(FunctionScoreMode.Max)
                .BoostMode(FunctionBoostMode.Multiply)
            )
        )
    );
    

    您可能想看看以下几点:

    1. description^1 可以简单地替换为 description,因为默认提升是 1
    2. 这可能更好地表示为bool 查询,每个权重函数中的每个查询都带有should 子句,并应用类似于使用权重的方式进行提升。像
    var response = client.Search<object>(s => s
        .Query(q => q
            .Bool(b => b
                .Must(mu => mu
                    .MultiMatch(mm => mm
                        .Query("AGC")
                        .Fields(new[] { "title^2", "description^1" })
                        .Type(TextQueryType.MostFields)
                        .Fuzziness(Fuzziness.AutoLength(4, 8))
                        .PrefixLength(2)
                        .Boost(5)
                    )
                )
                .Should(
                    sh => sh.Term(t => t
                        .Field("product")
                        .Value("A")
                        .Boost(45)
                    ),
                    sh => sh.Term(t => t
                        .Field("product")
                        .Value("B")
                        .Boost(20)
                    ),
                    sh => sh.Term(t => t
                        .Field("product")
                        .Value("C")
                        .Boost(10)
                    )
                )
            )
        )
    );
    

    【讨论】:

    • 非常感谢 - 成功了!我也采纳了你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多