ElasticSearch序列 - SpringBoot整合ES:根据指定的 ids 查询

Posted 我一直在流浪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch序列 - SpringBoot整合ES:根据指定的 ids 查询相关的知识,希望对你有一定的参考价值。

文章目录

1. ElasticSearch 根据 ids 查询文档

① 索引文档,构造数据

PUT /my_index/_doc/1

  "price":10


PUT /my_index/_doc/2

  "price":20


PUT /my_index/_doc/3

  "price":30

② 查询文档 id 为 1 或者 2 的文档:

GET /my_index/_search

  "query": 
    "ids": 
      "values": [1,2]
    
  


  "took" : 1,
  "timed_out" : false,
  "_shards" : 
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  ,
  "hits" : 
    "total" : 
      "value" : 2,
      "relation" : "eq"
    ,
    "max_score" : 1.0,
    "hits" : [
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : 
          "price" : 10
        
      ,
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : 
          "price" : 20
        
      
    ]
  

我们索引文档时,文档的id为整型,为什么查询出来的文档 id为字符串类型呢?如果我们使用字符串类型的文档id查询呢?

GET /my_index/_search

  "query": 
    "ids": 
      "values": ["1","2"]
    
  


  "took" : 2,
  "timed_out" : false,
  "_shards" : 
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  ,
  "hits" : 
    "total" : 
      "value" : 2,
      "relation" : "eq"
    ,
    "max_score" : 1.0,
    "hits" : [
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : 
          "price" : 10
        
      ,
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : 
          "price" : 20
        
      
    ]
  

可以看到仍然可以查询到匹配的文档。

在Elasticsearch中,文档ID可以是任何字符串类型,包括数字、字母、符号等。即使您在索引文档时使用了整数作为ID,Elasticsearch也会将其转换为字符串类型,并将其存储在内部索引中。当您查询文档时,Elasticsearch会将文档ID作为字符串类型返回。

如果您需要将查询结果中的文档ID转换为整数类型,可以在查询结果中进行转换。例如,在使用Java API执行查询时,您可以使用以下代码将文档ID转换为整数类型:

SearchResponse response = client.prepareSearch("my_index")
        .setQuery(QueryBuilders.matchAllQuery())
        .get();

for (SearchHit hit : response.getHits().getHits()) 
    int id = Integer.parseInt(hit.getId());
    // do something with the integer ID

在上面的代码中,我们首先执行一个查询,并使用getHits方法获取查询结果。然后,我们遍历查询结果中的每个文档,并使用Integer.parseInt方法将文档ID转换为整数类型。

2. SpringBoot整合ES实现 ids 查询

GET /my_index/_search

  "query": 
    "ids": 
      "values": [1,2]
    
  

@Slf4j
@Service
public class ElasticSearchImpl 

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void searchUser() throws IOException 
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // ids 查询
        IdsQueryBuilder idsQueryBuilder = new IdsQueryBuilder();
        // IdsQueryBuilder addIds(String... ids) 
        idsQueryBuilder.addIds("1", "2");
        searchSourceBuilder.query(idsQueryBuilder);

        SearchRequest searchRequest = new SearchRequest(new String[]"my_index",searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(searchResponse);
    

如果我们想根据 ids 去查询文档的话,一般会使用 terms 查询:

GET /my_index/_search

  "query": 
    "terms": 
      "_id": [
        "1",
        "2"
      ]
    
  

需要注意的是主键为_id,而不是id,如果使用id则查询结果会为空。

@Slf4j
@Service
public class ElasticSearchImpl 

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public void searchUser() throws IOException 
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // terms 查询
        List<String> ids = Arrays.asList("1","2");
        TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("_id",ids);
        searchSourceBuilder.query(termsQueryBuilder);

        SearchRequest searchRequest = new SearchRequest(new String[]"my_index",searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(searchResponse);
    


  "took" : 2,
  "timed_out" : false,
  "_shards" : 
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  ,
  "hits" : 
    "total" : 
      "value" : 2,
      "relation" : "eq"
    ,
    "max_score" : 1.0,
    "hits" : [
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : 
          "price" : 10
        
      ,
      
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : 
          "price" : 20
        
      
    ]
  

ElasticSearch返回不同的type的序列化

总体思路是:

利用json序列化的别名方法,反序列化到不同的字段上;

因为别名方法不支持多个别名,所以不得不根据不同的type,定义了多套适配内容。

最终在属性上进行选择。

 

本示例ElasticSearch返回的json串形如:

{

    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 3.4698925,
        "hits": [
            {
                "_index": "user",
                "_type": "userinfo",
                "_id": "1031014642252640",
                "_score": 3.4698925,
                "_source": {
                    "uid": 1031014642252640,
                    "level": 20
                }
            }
            ,
            {
                "_index": "user",
                "_type": "good",
                "_id": "1",
                "_score": 0.06378032,
                "_source": {
                    "id": 1,
                    "name": "good luck"
                }
            }
        ]
    }

}

 

 

using PlainElastic.Net;
using PlainElastic.Net.Queries;
using PlainElastic.Net.Serialization;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace TestQuery
{
    [Serializable]
    public class Show
    {
        /* A实体反序列化内容 */
        [JsonProperty(PropertyName = "uid")]
        private string title_1;
        [JsonProperty(PropertyName = "level")]
        private string content_1;

        /* B实体反序列化内容 */
        [JsonProperty(PropertyName = "id")]
        private string title_2;

        [JsonProperty(PropertyName = "name")]
        private string content_2;

        /* AB实体反序列化内容汇总返回 */
        public string Title
        {
            get
            {
                return title_1 ?? title_2;
            }
        }
        public string Content
        {
            get
            {
                return content_1 ?? content_2;
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var query = new QueryBuilder<Object>()
                .Query(q =>
                            q.Bool(b =>
                                        b.Should(m =>
                                                    m.Term(tm =>
                                                                {
                                                                    tm.Field("uid");
                                                                    tm.Value("1031014642252640");
                                                                    return tm;
                                                                }).Custom(@"{
                                                                      ""exists"": {
                                                                            ""field"": ""name""
                                                                      }
                                                                    }")
                                                  )
                                    )
                            )
            .From(0)
            .Size(100)
            //.Sort(s => s.Field(UserInfoField.level, SortDirection.desc))
            .BuildBeautified();
            Console.WriteLine(query);
            List<Show> list = new List<Show>();
            var cmd = new SearchCommand("user");
            var client = new ElasticConnection("localhost", 9200);
            var operationResult = client.Post(cmd, query);
            var serializer = new JsonNetSerializer();
            var hits = serializer.ToSearchResult<Show>(operationResult).hits;
            var serializerResult = hits.hits;
            //页面显示实体
            //
            foreach (var item in serializerResult)
            {
                list.Add(item._source);
            } 
  
        }
    }
}

 

以上是关于ElasticSearch序列 - SpringBoot整合ES:根据指定的 ids 查询的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Elasticsearch 序列化 AWSDate

ElasticSearch返回不同的type的序列化

.NET(C#)通过JSON.NET反序列化Elasticsearch返回响应的结果

未反序列化Spring Data Elasticsearch文档

ElasticSearch序列 - SpringBoot整合ES:根据指定的 ids 查询

ElasticSearch序列 - SpringBoot整合ES:范围查询 range