【问题标题】:NEST: Add Term Query Under ConditionNEST:在条件下添加词条查询
【发布时间】:2017-06-20 20:58:56
【问题描述】:

在我的应用程序中,我将一个布尔参数传递给一个函数,该函数通过HasChildQuery 在我的弹性索引中搜索某些文档。
如果此布尔值设置为 false,我想排除具有特定字段集的文档,当布尔值设置为 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 为假。
但是如果是真的情况的查询似乎不起作用。

我希望&amp;&amp; (includeAutoLearnedData ? null : +new TermQuery 仅在布尔值为 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:
{}

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

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

    1. field 分配了一个空字符串,或者一个null 字符串、表达式或属性
    2. 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 中缺少关于无条件查询的部分。将添加一个!)

    【讨论】:

    • 哦,我想很明显我的查询不是空的。我认为他们的内容只会给我的问题增加不必要的混乱,这无助于任何人理解我的问题。我将编辑我的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多