使用Nest进行弹性搜索查询,不仅可以搜索文本,还可以按标志进行过滤

时间:2018-11-16 12:47:55

标签: elasticsearch nest

我有以下查询:

return Q
    .MultiMatch(Fu => Fu
        .Fields(F => F
            .Field(Ff => Ff.Tags)
            .Field(Ff => Ff.Title)
        )
        .Query(Terms)
        .Fuzziness(Fuzziness.EditDistance(2))
    );

如何向要执行的查询中添加次要部分:

“如果文档中没有'score'字段,或者''score'<= 1”

我看不到如何用API添加此部分。

1 个答案:

答案 0 :(得分:1)

假设POCO类似

public class MyDocument 
{
    public string[] Tags { get; set; }

    public string Title { get; set; }

    public int Score { get; set; }
}

您可以使用overloaded operators on queries来构造复合布尔查询,以满足要求

var client = new ElasticClient(settings);

var terms = "foo bar baz";

var searchResponse = client.Search<MyDocument>(s => s
    .Query(q => q
        .MultiMatch(mm => mm
            .Fields(f => f
                .Field(ff => ff.Tags)
                .Field(ff => ff.Title)
            )
            .Query(terms)
            .Fuzziness(Fuzziness.EditDistance(2))
        ) && +(!q
        .Exists(e => e
            .Field(f => f.Score)
        ) || q
        .Range(r => r
            .Field(f => f.Score)
            .LessThan(1)
        ))
    )
); 

这将导致查询

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "foo bar baz",
            "fuzziness": 2,
            "fields": [
              "tags",
              "title"
            ]
          }
        }
      ],
      "filter": [
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "must_not": [
                    {
                      "exists": {
                        "field": "score"
                      }
                    }
                  ]
                }
              },
              {
                "range": {
                  "score": {
                    "lt": 1.0
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

这是查询的更简洁形式

var searchResponse = client.Search<MyDocument>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(mu => mu
                .MultiMatch(mm => mm
                    .Fields(f => f
                        .Field(ff => ff.Tags)
                        .Field(ff => ff.Title)
                    )
                    .Query(terms)
                    .Fuzziness(Fuzziness.EditDistance(2))
                )
            )
            .Filter(fi => fi
                .Bool(bb => bb
                    .Should(sh => sh
                        .Bool(bbb => bbb
                            .MustNot(mn => mn
                                .Exists(e => e
                                    .Field(f => f.Score)
                                )
                            )
                        ), sh => sh
                        .Range(r => r
                            .Field(f => f.Score)
                            .LessThan(1)
                        )
                    )
                )
            )
        )
    )
); 
相关问题