NEST-术语为空时,MultiMatch搜索所有文档-Elasticsearch 6.4

时间:2018-11-09 10:49:44

标签: c# elasticsearch nest

我正在尝试使用NEST和multimatch选项进行查询,但是结果没有按预期出来。

我提交了一个应与多个字段进行比较的术语。但是,如果未设置搜索词,则必须返回所有文档。

我看到可以使用诸如“ *。*”之类的关键字,但这没有用。 有什么建议吗?

var searchResponse = client.Search<DocumentElasticModel>(s => s
              .Size(pageSize)
              .Skip(currentPageIndex * pageSize)
              .Sort(ss => ss
                .Descending(SortSpecialField.Score)
              )
              .Source(sf => sf
                .Includes(i => i
                    .Fields(
                        returnedFields
                    )
                )
              )
              .Query(q => q
                .Nested(c => c
                    .Name("named_query")
                    .Boost(1.1)
                    .InnerHits(i => i.Explain())
                    .Path(p => p.PerguntasRespostas)
                    .Query(nq => nq
                        .MultiMatch(m => m
                            .Fields(f => filterFields) 
-----------------------WHEN THE 'SEARCH' IS EMPTY, SHOULD FIND ALL -----------------
                            .Query(string.IsNullOrEmpty(search) ? string.Empty : search)
                        )
                    )
                    .IgnoreUnmapped()
                )
              )

1 个答案:

答案 0 :(得分:0)

默认情况下,NEST支持此概念,该概念称为Conditionless queries。您可以

private static void Main()
{
    var defaultIndex = "documents";
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

    var settings = new ConnectionSettings(pool, new InMemoryConnection())
        .DefaultIndex(defaultIndex)
        .DisableDirectStreaming()
        .PrettyJson()
        .OnRequestCompleted(callDetails =>
        {
            if (callDetails.RequestBodyInBytes != null)
            {
                Console.WriteLine(
                    $"{callDetails.HttpMethod} {callDetails.Uri} \n" +
                    $"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
            }
            else
            {
                Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
            }

            Console.WriteLine();

            if (callDetails.ResponseBodyInBytes != null)
            {
                Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                         $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
                         $"{new string('-', 30)}\n");
            }
            else
            {
                Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
                         $"{new string('-', 30)}\n");
            }
        });

    var client = new ElasticClient(settings);

    var pageSize = 20;
    var currentPageIndex = 0;  
    string search = "foo";


    var searchResponse = client.Search<DocumentElasticModel>(s => s
        .Size(pageSize)
        .Skip(currentPageIndex * pageSize)
        .Sort(ss => ss
            .Descending(SortSpecialField.Score)
        )
        .Source(sf => sf
            .Includes(i => i
                .Fields(f => f.TopLevelMessage)
            )
        )
        .Query(q => q
            .Nested(c => c
                .Name("named_query")
                .Boost(1.1)
                .InnerHits(i => i.Explain())
                .Path(p => p.PerguntasRespostas)
                .Query(nq => nq
                    .MultiMatch(m => m
                        .Fields(f => f
                            .Field(ff => ff.PerguntasRespostas.First().Message)
                        ) 
                        .Query(search)
                    )
                )
                .IgnoreUnmapped()
            )
        )
    );
}


public class DocumentElasticModel 
{
    public string TopLevelMessage { get; set; }

    public IEnumerable<PerguntasRespostas> PerguntasRespostas {get;set;}
}

public class PerguntasRespostas
{
    public string Message { get; set; }  
}

这将发送以下查询

POST http://localhost:9200/documents/documentelasticmodel/_search
{
  "from": 0,
  "size": 20,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ],
  "_source": {
    "includes": [
      "topLevelMessage"
    ]
  },
  "query": {
    "nested": {
      "_name": "named_query",
      "boost": 1.1,
      "query": {
        "multi_match": {
          "query": "foo",
          "fields": [
            "perguntasRespostas.message"
          ]
        }
      },
      "path": "perguntasRespostas",
      "inner_hits": {
        "explain": true
      },
      "ignore_unmapped": true
    }
  }
}

现在,如果将search更改为string.Emptynull,您将得到

POST http://localhost:9200/documents/documentelasticmodel/_search
{
  "from": 0,
  "size": 20,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ],
  "_source": {
    "includes": [
      "topLevelMessage"
    ]
  }
}

请求中没有明确的"query",这与match_all查询相同。

如果您想覆盖NEST中的无条件查询功能,则可以将查询标记为.Verbatim(),然后NEST会按原样发送

var searchResponse = client.Search<DocumentElasticModel>(s => s
    .Size(pageSize)
    .Skip(currentPageIndex * pageSize)
    .Sort(ss => ss
        .Descending(SortSpecialField.Score)
    )
    .Source(sf => sf
        .Includes(i => i
            .Fields(f => f.TopLevelMessage)
        )
    )
    .Query(q => q
        .Nested(c => c
            .Verbatim() // <-- mark the nested query
            .Name("named_query")          
            .Boost(1.1)
            .InnerHits(i => i.Explain())
            .Path(p => p.PerguntasRespostas)
            .Query(nq => nq
                .MultiMatch(m => m
                    .Verbatim() // <-- mark the inner query
                    .Fields(f => f
                        .Field(ff => ff.PerguntasRespostas.First().Message)
                    ) 
                    .Query(search)
                )
            )
            .IgnoreUnmapped()
        )
    )
);

发送

POST http://localhost:9200/documents/documentelasticmodel/_search
{
  "from": 0,
  "size": 20,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ],
  "_source": {
    "includes": [
      "topLevelMessage"
    ]
  },
  "query": {
    "nested": {
      "_name": "named_query",
      "boost": 1.1,
      "query": {
        "multi_match": {
          "fields": [
            "perguntasRespostas.message"
          ]
        }
      },
      "path": "perguntasRespostas",
      "inner_hits": {
        "explain": true
      },
      "ignore_unmapped": true
    }
  }
}

您需要检查这是否是Elasticsearch接受的有效查询。