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 查询的主要内容,如果未能解决你的问题,请参考以下文章
.NET(C#)通过JSON.NET反序列化Elasticsearch返回响应的结果
未反序列化Spring Data Elasticsearch文档