ElasticSearch 将嵌套字段的 Rest 查询转换为客户端 Scala/Java 代码

Posted

技术标签:

【中文标题】ElasticSearch 将嵌套字段的 Rest 查询转换为客户端 Scala/Java 代码【英文标题】:ElasticSearch Convert Rest Query for nested field to client Scala/Java code 【发布时间】:2022-01-16 19:14:29 【问题描述】:

我找不到有关如何将嵌套查询从 ES官方示例转成Scala/Java代码

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

GET my-index-000001/_search

  "query": 
    "nested": 
      "path": "user",
      "query": 
        "bool": 
          "must": [
             "match":  "user.first": "Alice" ,
             "match":  "user.last":  "Smith"  
          ]
        
      
    
  

在 Scala 中我尝试过

  import org.elasticsearch.index.query.QueryBuilders._
  ...

  val q = boolQuery()
  q.must(termQuery("user.first", "Alice"))
  q.must(termQuery("user.last", "White))
  nestedQuery("user", q, ScoreMode.None)
        

但在检查结果查询时却不一样。

生成的查询类似于(它的裁剪版本,因为原始查询要大得多):

 "nested" : 
                            "query" : 
                              "bool" : 
                                "must" : [
                                  
                                    "match" : 
                                      "user.first" : 
                                        "query" : "Alice",
                                        "operator" : "OR",
                                        "prefix_length" : 0,
                                        "max_expansions" : 50,
                                        "fuzzy_transpositions" : true,
                                        "lenient" : false,
                                        "zero_terms_query" : "NONE",
                                        "auto_generate_synonyms_phrase_query" : true,
                                        "boost" : 1.0
                                      
                                    
                                  ,
                                  
                                    "match" : 
                                      "user.last" : 
                                        "query" : "Smith",
                                        "operator" : "OR",
                                        "prefix_length" : 0,
                                        "max_expansions" : 50,
                                        "fuzzy_transpositions" : true,
                                        "lenient" : false,
                                        "zero_terms_query" : "NONE",
                                        "auto_generate_synonyms_phrase_query" : true,
                                        "boost" : 1.0
                                      
                                    
                                  
                                ],
                                "adjust_pure_negative" : true,
                                "boost" : 1.0
                              
                            ,
                            "path" : "user",
                            "ignore_unmapped" : false,
                            "score_mode" : "none",
                            "boost" : 1.0
                          
                        

我得到的实际异常是在单元测试中:

. java.io.NotSerializableException: org.elasticsearch.client.Response
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputSt[info] - should excluded keywords only *** FAILED ***
[info]   org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
[info]   at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:176)
[info]   at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1933)
[info]   at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1910)
[info]   at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1667)
[info]   at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1624)
ream.java:1509)
    at java.io.Obje[info]   at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1594)
[info]   at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:1110)

【问题讨论】:

您能否通过您的 Scala 代码发布输出查询。因为据我所知,当您打印最终的 DSL 查询时,Java 客户端代码也会添加一些默认参数。 感谢您的建议。我已经编辑了帖子以包含示例输出(实际查询要大得多)。 【参考方案1】:

您的 Scala 代码正在生成正确的查询。基本上这里发生的是,它在查询中添加了一些带有值的默认参数,因此,与原始查询相比,您的查询看起来更大。这由 Java 和 Scala elasticsearch 客户端完成(可能是其他语言客户端也在做同样的事情)。此外,当您在 Kibana 中创建 DSL 查询时,运行时会将所有默认参数添加到您的查询中。

以下是查询中具有默认值的参数:

"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1.0

下面我已经删除了通过代码添加到您的查询中的所有默认参数:


    "nested": 
        "query": 
            "bool": 
                "must": [
                    
                        "match": 
                            "user.first": 
                                "query": "Alice"
                            
                        
                    ,
                    
                        "match": 
                            "user.last": 
                                "query": "Smith"
                            
                        
                    
                ]
            
        ,
        "path": "user"
        
    

【讨论】:

@vpetrescu 您没有在问题中添加该异常。所以我以为你只是要求澄清。请同时添加异常详细信息。你得到什么异常? 谢谢,我知道额外的默认参数。我想知道添加“查询”一词。 "match": "user.first": "query": "Alice" 与简单的 "match": "user.first": "Alice",.. "match": "user.first": "query": "Alice" 和 "match": "user.first": "Alice",.. 都查询是一样的。它正在添加查询子句作为添加默认参数。 谢谢!查询确实是一样的。该错误是由代码的其他部分产生的。

以上是关于ElasticSearch 将嵌套字段的 Rest 查询转换为客户端 Scala/Java 代码的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework:将嵌套 json 字段中的数据序列化为普通对象

Django REST Framework 序列化程序中的嵌套注释字段

elasticsearch-rest-high-level-client操作elasticsearch

elasticsearch-rest-high-level-client操作elasticsearch

elasticsearch-rest-high-level-client操作elasticsearch

elasticsearch-rest-high-level-client操作elasticsearch