Эластичный поисковый запрос с Nest, поиск текста, но также фильтрация по флагам - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть следующий запрос:

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

Как добавить дополнительную часть к запросу, который будет выполняться:

"Если в документе НЕТ поля 'Score' ИЛИ, если'оценка' <= 1 "</p>

Я не вижу, как добавить эту часть с помощью API.

1 Ответ

0 голосов
/ 19 ноября 2018

Предполагая, что POCO что-то вроде

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

    public string Title { get; set; }

    public int Score { get; set; }
}

Вы можете использовать перегруженные операторы для запросов для составления составных запросов bool, чтобы удовлетворить требования

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)
                        )
                    )
                )
            )
        )
    )
); 
...