【问题标题】:Elasticsearch: how to prevent my client from automatically inserting the top-level query propertyElasticsearch:如何防止我的客户端自动插入顶级查询属性
【发布时间】:2015-03-13 23:23:50
【问题描述】:

我需要生成一个结构如下的查询字符串:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
       ....
      }
    }
  },
  "aggregations": {
    "facets": {
      "terms": {
        "field": "subject"
      }
    }
  }
}

我正在使用以下客户端进行搜索:

Client client = new TransportClient(my_settings_object)
        .addTransportAddress(new InetSocketTransportAddress("localhost", "9200"));
SearchResponse sr = client.prepareSearch("my_index")
        .setTypes("my_doctype")
        .setQuery(query) ; // this is above query string built manually
        .execute().actionGet();         
return sr;

我收到以下错误:

QueryParsingException[[my_idex] No query registered for [query]]

这个SO帖子似乎解释了这个错误:

elasticsearch - No query registered for [query]]

基本上,我的客户端会自动插入顶级查询属性,使其看起来像:

{
    query:  {
      "query": {
        "filtered": {
          "query": {
            "match_all": {}
          },
          "filter": {
           ....
          }
        }
      },
      "aggregations": {
        "facets": {
          "terms": {
            "field": "subject"
          }
        }
      }
    }
}

如何防止我的客户端自动插入顶级查询属性?

感谢和问候。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    让您的查询和聚合查询单个 JSON 对象。将查询更改为:

    {
        "filtered": {
            "query": {
                "match_all": {
    
                }
            },
            "filter": {
                ....
            }
        }
    }
    

    并更改聚合,使它们位于单独的 JSON 对象中:

        {
            "facets": {
                "terms": {
                    "field": "subject"
                }
            }
        }
    

    在 SearchRequestBuilder 中设置查询和聚合:

    SearchResponse sr = client.prepareSearch("my_index")
        .setTypes("my_doctype")
        .setQuery(query) ; // this is above query string built manually
        .setAggregations(aggregations.getBytes());
        .execute().actionGet(); 
    

    【讨论】:

    • 您好,丹,我正在尝试您的方法。我用谷歌搜索,似乎找不到如何用字符串构建 BytesReference 对象的示例。我相信你的方法应该有效,但 setAggregations(aggregations) 需要一个 BytesReference 对象。您是否碰巧有任何链接用于从字符串中创建 BytesReference 对象?或者通过创建 BytesReference 对象来更新您的答案?谢谢!!!
    • 只需将字符串转换为字节:aggregationsJson.getBytes()
    • 丹,我试了一下,编译出错。 aggregations_string.getBytes() 返回 byte[],它不是 BytesReference。我错过了什么明显的东西吗?
    • setAggregations 方法接受一个字节数组作为参数public SearchRequestBuilder setAggregations(byte[] aggregations) {,在 Elasticsearch 源代码的SearchRequestBuilder 类中。所以你不应该得到一个编译错误。您使用的是哪个版本的 Elasticsearch?
    • Elasticsearch 中的BytesArray 类实现了BytesReference 接口,因此您可以像这样设置聚合:searchRequestBuilder.setAggregations(new BytesArray(aggregationsJsonAsString));
    【解决方案2】:

    如何在 Java 代码中构建 query 对象?

    尝试使用QueryBuilders.filteredQuery(...)进行准备:调用SearchRequestBuilder的相关setter时,结果将被包裹在query属性中。

    【讨论】:

    • Thomas,我以这种方式手动构建查询: query = "{ query: " + query_string + "," + aggregation_string + "}" 。我有一个相当复杂的过滤查询,我希望继续使用。
    猜你喜欢
    • 1970-01-01
    • 2011-12-12
    • 2016-03-27
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    相关资源
    最近更新 更多