c# - NEST:在条件下添加术语查询

标签 c# elasticsearch nest

在我的应用程序中,我将 bool(boolean) 参数传递给一个函数,该函数通过HasChildQuery在我的 flex 索引中搜索某些文档。
如果此 bool(boolean) 值设置为false,则我想排除具有特定字段集的文档,当 bool(boolean) 值设置为true时,我不希望出现第二种情况。

到目前为止,这是我的方法:

Query = new HasChildQuery                                         
{                                                                 
    // ...                               
    Query = new CommonTermsQuery                                  
    {                                                             
        // This Query always needs to be there  
        Field = Nest.Infer.Field<FaqQuestion>(q => q.Content), 
        Query = content                                   
    }                                                             
    && (includeAutoLearnedData ? null : +new TermQuery            
    {                                                             
        // I only want this Query if includeAutoLearnedData is false    
        Field = Nest.Infer.Field<FaqQuestion>(q => q.AutoLearned),  
        Value = false             
    })                                                            
}                                                                 

我的想法是始终生成这样的请求
has_child
|
|__ ...
|
|__ common_terms

并扩展到
has_child
|
|__ ...
|
|__ bool
    |
    |__must
    |  |
    |  |__common_terms
    |  
    |__filter
       |
       |__term

如果includeAutoLearnedData为false。
但是查询为真的情况似乎不起作用。

我希望&& (includeAutoLearnedData ? null : +new TermQuery仅在boolean为false时才添加过滤器,而在true时不修改查询

那么在NEST中的特定条件下包括附加过滤器查询的正确方法是什么?

编辑:
当我从ElasticClient获得结果并希望它具有类似以下内容时,我设置了一个断点
Valid NEST response built from a successful low level call on POST: /faq/_search
# Audit trail of this API call:
 - [1] HealthyResponse: Node: http://localhost:9200/ Took: 00:00:00.0770000
# Request:
{
    "query": {
        "has_child": {
             "bool": {
                 "must": [{
                     "common_terms": { ... }
                 }],
                 "filter": [{
                     "term": { ... }
                 }]
             }
         }
    }
}

但实际结果有:
# Request:
{}

最佳答案

您所拥有的是正确的,并且您的方法是正确的,但是在输出中看到{}的原因是由于NEST中的无条件查询;本质上,如果查询未设置某些属性(或者为它们分配了null或空字符串),则该查询被视为无条件的,并且不会作为请求的一部分进行序列化。例如,对于term查询,如果

  • field分配了一个空字符串,或者是null字符串,表达式或属性
  • valuenull或空字符串

  • term查询被认为是无条件的。您可以使用 verbatim and strict 更改此行为
    Verbatim
    可以将单个查询标记为逐字查询,这意味着即使无条件查询也应像一样发送给Elasticsearch
    Strict
    可以将各个查询标记为严格的含义,即如果它们是无条件的,则会引发异常。当查询必须具有输入值时,这很有用。

    证明您的方法有效
    void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var defaultIndex = "default-index";
        var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection())
            .DefaultIndex(defaultIndex)
            .PrettyJson()
            .DisableDirectStreaming()
            .OnRequestCompleted(response =>
                {
                    if (response.RequestBodyInBytes != null)
                    {
                        Console.WriteLine(
                            $"{response.HttpMethod} {response.Uri} \n" +
                            $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
                    }
                    else
                    {
                        Console.WriteLine($"{response.HttpMethod} {response.Uri}");
                    }
    
                    Console.WriteLine();
    
                    if (response.ResponseBodyInBytes != null)
                    {
                        Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                 $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
                                 $"{new string('-', 30)}\n");
                    }
                    else
                    {
                        Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                 $"{new string('-', 30)}\n");
                    }
                });
    
        var client = new ElasticClient(connectionSettings);
    
        var includeAutoLearnedData = false;
    
        var request = new SearchRequest<Message>
        {
            Query = new HasChildQuery
            {          
                Type = "child",
                Query = new CommonTermsQuery
                {
                    Field = Infer.Field<Message>(m => m.Content),
                    Query = "commonterms"
                }
                && (includeAutoLearnedData ? null : +new TermQuery
                {
                    Field = Infer.Field<Message>(m => m.Content),
                    Value = "term"
                })
            }
        };
    
        client.Search<Message>(request);
    }
    
    public class Message
    {
        public string Content { get; set; }
    }
    

    includeAutoLearnedDatafalse时产生以下查询
    {
      "query": {
        "has_child": {
          "type": "child",
          "query": {
            "bool": {
              "must": [
                {
                  "common": {
                    "content": {
                      "query": "commonterms"
                    }
                  }
                }
              ],
              "filter": [
                {
                  "term": {
                    "content": {
                      "value": "term"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    当它是true
    {
      "query": {
        "has_child": {
          "type": "child",
          "query": {
            "common": {
              "content": {
                "query": "commonterms"
              }
            }
          }
        }
      }
    }
    

    (我注意到我们在 latest documentation 中缺少关于无条件查询的部分。将添加一个!)

    关于c# - NEST:在条件下添加术语查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44651876/

    相关文章:

    amazon-web-services - AWS Kinesis Firehose 到 ElasticSearch 地理数据映射

    elasticsearch - 怎么通过id搜索呢?

    c# - 从上周的mysql查询中选择数据

    c# - 从 HTML 导出到 PDF (C#)

    c# - 将 YAML 反序列化为自定义类型

    c# - Elasticsearch Nest Client - 搜索嵌套属性

    elasticsearch - 查询ElasticSearch数据时进行转换

    c# - 将字节数组设置为unity texture2d的快速方法

    elasticsearch - 如何找出在Elasticsearch 6.4中加入或离开的节点

    elasticsearch - 聚合查询的Elasticsearch验证