代码之家  ›  专栏  ›  技术社区  ›  TheJeff

基于JSON结构的Spring数据弹性搜索查询

  •  0
  • TheJeff  · 技术社区  · 8 年前

    https://www.programcreek.com/java-api-examples/index.php?api=org.springframework.data.elasticsearch.annotations.Query

    我想知道是否有一种方法可以通过elasticsearch java库通过完整的JSON主体进行查询,而不需要注释。也就是说,在一个方法实现或什么的内部。这将帮助我分析响应中的突出显示等。。

    谢谢你提供任何信息。

    评论澄清:我使用的是SpringDataElasticSearch3.0.10.RELEASE和ElasticSearch6。由于spring数据elasticsearch似乎还不支持RestHighLevelClient,所以我使用TransportClient=new PreBuiltTransportClient(elasticsearchSettings);创建ElasticsearchTemplate时的方法:返回新的ElasticsearchTemplate(client());

    2 回复  |  直到 8 年前
        1
  •  2
  •   tom    8 年前

    我想出了一个方法,但它需要你做一个脚本,生活在弹性节点。看到了吗 File-based scripts

    创建一个名为 template_doctype.mustache 并将其复制到 $ELASTIC_HOME/config/scripts

    {
        "query" : {
            "match" : {
                "type" : "{{param_type}}"
            }
        }
    }
    

    我的 pom.xml 依赖项:

    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.0.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>5.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    

    mvn dependency:tree spring-data-elasticsearch 隐式使用ElasticSearch库的5.5版本,即使您使用的是ElasticSearch 6。)

    curl -X PUT http://localhost:9200/myindex
    

    创建两个可用于匹配的文档,以确保代码正常工作:

    curl -X POST http://localhost:9200/myindex/mydoc -d '{"title":"foobar", "type":"book"}'
    curl -X POST http://localhost:9200/myindex/mydoc -d '{"title":"fun", "type":"magazine"}'
    

    尝试运行查询。此代码应返回单个文档:

    String clusterName = "my-application";
    Settings elasticsearchSettings = Settings.builder().put("cluster.name", clusterName).build();
    TransportClient client = new PreBuiltTransportClient(elasticsearchSettings)
            .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9300));
    Map<String, Object> template_params = new HashMap<>();
    
    // Here is where you put parameters to your script.
    template_params.put("param_type", "book");
    SearchResponse sr = new SearchTemplateRequestBuilder(client)
            .setScript("template_doctype")  // this is where you specify what template to use
            .setScriptType(ScriptType.FILE)
            .setScriptParams(template_params)
            .setRequest(new SearchRequest())
            .get()
            .getResponse();
    
    SearchHit[] results = sr.getHits().getHits();
    for(SearchHit hit : results){
    
        String sourceAsString = hit.getSourceAsString();
        if (sourceAsString != null) {
            Gson gson = new GsonBuilder().setPrettyPrinting()
                    .create();
            Map map = gson.fromJson(sourceAsString, Map.class);
            System.out.println( gson.toJson(map));
        }
    }
    

    {
      "title": "foobar",
      "type": "book"
    }
    
        2
  •  1
  •   tom    8 年前

    将这些依赖项添加到 pom.xml

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.19</version>
        <scope>compile</scope>
    </dependency>
    

    然后执行以下操作:

    import com.sun.jersey.api.client.Client;
    import com.sun.jersey.api.client.ClientResponse;
    import com.sun.jersey.api.client.WebResource;
    
    Client client = new Client();
    final WebResource r = client.resource("http://localhost:9200").path("/myindex/_search");
    String requestJson = "{\"query\" : {\"match\" : {\"type\" : \"book\"} }}";
    ClientResponse response = r.post(ClientResponse.class, requestJson);
    String json = response.getEntity(String.class);
    
    Gson gson = new GsonBuilder().setPrettyPrinting()
            .create();
    Map map = gson.fromJson(json, Map.class);
    System.out.println(gson.toJson(map));
    
    // to convert to SearchResponse:
    JsonXContentParser xContentParser = new JsonXContentParser(NamedXContentRegistry.EMPTY,
                new JsonFactory().createParser(json));
    SearchResponse searchResponse = SearchResponse.fromXContent(xContentParser);
    

    输出示例:

    {
        "took": 9.0,
        "timed_out": false,
        "_shards": {
            "total": 5.0,
            "successful": 5.0,
            "failed": 0.0
        },
        "hits": {
            "total": 1.0,
            "max_score": 0.2876821,
            "hits": [
            {
                "_index": "myindex",
                "_type": "mydoc",
                "_id": "AWXp8gZjXyu6lA_2Kpi2",
                "_score": 0.2876821,
                "_source": {
                    "title": "foobar",
                    "type": "book"
                }
            }
            ]
        }
    }
    
    推荐文章