在NEST中无法重新创建弹性搜索查询

时间:2019-02-09 19:43:52

标签: elasticsearch nest

我正在尝试将Kibana开发人员的查询重新创建到NEST中,但结果却不尽相同。

我在Kibana中运行的查询可以完美地返回1个结果

这是我的Kibana查询:

var $submit = $('#submit-form');
   $submit.off('click').on('click', function(e) {
       e.preventDefault();

       var checkedBOX = $('#checkboxes').find('input:checked');
       var servers = [];
       $.each(checkedBOX, function(k, v) {
           var v = $(v);

           servers.push(v.val());

           v.prop("checked", false);
       });

       var doneCount = 0;
       $.each(servers, function(key, server) {
           $.ajax({
           type: "POST",
           url: window.location.href,
           data: $('#form').serialize() + '&server=' + server + '&submit=',
           success: function (data) {
               doneCount++;

               if (doneCount >= servers.length) {
                   window.location.reload();
               }
           }
           })
       });
   });

当我在NEST中创建查询时,除了将 minimum_should_match 更改为1(然后返回2个结果)之外,它不会返回任何结果

这是我的NEST查询:

GET /cats/_doc/_search
{   
"query":{
    "bool" : {     
        "minimum_should_match" :3,
        "should": [
           {"term" : { "name" : "cats" }},
           {"term" : { "name" : "are" }},
           {"term" : { "name" : "craze" }}

         ]
      }
   }
}

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您没有在NEST中建立与在Kibana中相同的查询;前者正在使用terms查询,而后者正在term查询bool子句中使用三个should查询。这两个查询与“最少”匹配的语义不同。

NEST中的相同查询是

var client = new ElasticClient();

string[] tmp = "Cats are craze".ToLower().Split(new string[] { " " }, StringSplitOptions.None);
var from = 0;

var searchResponse = client.Search<dynamic>(s => s
    .From(from)
    .Size(20)
    .Query(q => q
        .Bool(b =>
        {
            b.MinimumShouldMatch(tmp.Length);
            var shouldQueries = 
                new List<Func<QueryContainerDescriptor<dynamic>, QueryContainer>>(tmp.Length);

            for (var i = 0; i < tmp.Length; i++)
            {
                var value = tmp[i];              
                shouldQueries.Add(qc => qc.Term(t => t
                    .Field("name")
                    .Value(value)
                ));
            }

            b.Should(shouldQueries);

            return b;
        })
    )
);

它将构建以下查询

{
  "from": 0,
  "query": {
    "bool": {
      "minimum_should_match": 3,
      "should": [
        {
          "term": {
            "name": {
              "value": "cats"
            }
          }
        },
        {
          "term": {
            "name": {
              "value": "are"
            }
          }
        },
        {
          "term": {
            "name": {
              "value": "craze"
            }
          }
        }
      ]
    }
  },
  "size": 20
}

在此示例中,当必须匹配的should子句的数量等于minimum_should_match时,实际上等于说它们都是must子句(没有minimum_should_match)

var client = new ElasticClient();

string[] tmp = "Cats are craze".ToLower().Split(new string[] { " " }, StringSplitOptions.None);
var from = 0;

var searchResponse = client.Search<dynamic>(s => s
    .From(from)
    .Size(20)
    .Query(q => 
        tmp.Aggregate((QueryContainer)null, (qc, v) => qc && q.Term("name", v))
    )
);

利用operator overloading on NEST queries&&一起构建查询

{
  "from": 0,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": {
              "value": "cats"
            }
          }
        },
        {
          "term": {
            "name": {
              "value": "are"
            }
          }
        },
        {
          "term": {
            "name": {
              "value": "craze"
            }
          }
        }
      ]
    }
  },
  "size": 20
}