在嵌套对象的集合中搜索
Search in a collection of nested objects
我有 elasticSearch 7.4。我有一个 Address 模型和类型为 Entry:
的嵌套模型 'parts'
@Document(indexName = "address", createIndex = true)
public class Address {
@Id
@Field(type = FieldType.Text, store = true)
public String id;
@Field(type = FieldType.Text)
private String fullAddress;
private String regionCode;
private boolean customQuery = true;
private boolean root;
@Field(type = FieldType.Nested, store = true)
private List<Entry> parts;
@Field(type = FieldType.Nested, store = true)
private House house;
}
public class Entry {
private String aoid;
private String aoGuid;
private String code;
private String offName;
private String parentGuid;
private String shortName;
@Field(type = FieldType.Integer)
private Integer aoLevel;
private String postalCode;
}
我想在条目列表的 AoGuid 字段上编写搜索:
@Override
public List<Address> findForHouse(String aoguid) {
SearchSourceBuilder builder = new SearchSourceBuilder();
NestedQueryBuilder findByparts = nestedQuery(
"parts",
termQuery("parts.aoGuid", aoguid),
ScoreMode.None);
TermQueryBuilder findByRoot = termQuery("root", true);
QueryBuilder findByIdAndLocation = QueryBuilders.boolQuery()
.filter(findByRoot)
.filter(findByparts);
builder.query(findByIdAndLocation);
String[] strings = new String[]{"address"};
SearchRequest request = new SearchRequest(strings, builder);
try {
restHighLevelClient.search(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
当我调用搜索方法时,出现错误:
org.elasticsearch.ElasticsearchStatusException: Elasticsearch
exception [type=search_phase_execution_exception, reason=all shards
failed] at
org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177)
~[elasticsearch-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1727)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1704)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1467)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1424)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1394)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:930)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at
ru.evolenta.server.service.elastic.impl.ElasticQueryAddressServiceImpl.findForHouse(ElasticQueryAddressServiceImpl.java:117)
~[classes/:na] at
ru.evolenta.server.service.async.impl.AsyncHouseElasticServiceImpl.lambda$saveFias(AsyncHouseElasticServiceImpl.java:45)
~[classes/:na] at
java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
~[na:1.8.0_201] at
java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
~[na:1.8.0_201] at
java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
~[na:1.8.0_201] at
java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
~[na:1.8.0_201] at
java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
~[na:1.8.0_201] at
java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
~[na:1.8.0_201] at
java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)
~[na:1.8.0_201] at
java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
~[na:1.8.0_201] at
java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
~[na:1.8.0_201] at
java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
~[na:1.8.0_201] at
java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
~[na:1.8.0_201] at
java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
~[na:1.8.0_201] at
java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583)
~[na:1.8.0_201] at
ru.evolenta.server.service.async.impl.AsyncHouseElasticServiceImpl.saveFias(AsyncHouseElasticServiceImpl.java:42)
~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method) ~[na:1.8.0_201] at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_201] at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_201] at java.lang.reflect.Method.invoke(Method.java:498)
~[na:1.8.0_201] at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338)
~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)
~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at
org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke[=12=](AsyncExecutionInterceptor.java:115)
~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at
java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
~[na:1.8.0_201] at
java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:1.8.0_201]
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
~[na:1.8.0_201] at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
~[na:1.8.0_201] at java.lang.Thread.run(Thread.java:748)
~[na:1.8.0_201] Suppressed:
org.elasticsearch.client.ResponseException: method [POST], host
[http://localhost:9200], URI
[/address/_search?typed_keys=true&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true],
status line [HTTP/1.1 400 Bad Request]
{"error":{"root_cause":[{"type":"query_shard_exception","reason":"failed
to create query: {\n \"bool\" : {\n \"filter\" : [\n {\n
\"term\" : {\n \"root\" : {\n \"value\" : true,\n
\"boost\" : 1.0\n }\n }\n },\n {\n
\"nested\" : {\n \"query\" : {\n \"term\" : {\n
\"parts.aoGuid\" : {\n \"value\" :
\"2d598ce8-feaf-4fb0-9320-bcad370a5d52\",\n \"boost\" :
1.0\n }\n }\n },\n \"path\" : \"parts\",\n \"ignore_unmapped\" : false,\n
\"score_mode\" : \"none\",\n \"boost\" : 1.0\n }\n
}\n ],\n \"adjust_pure_negative\" : true,\n \"boost\" : 1.0\n
}\n}","index_uuid":"jqAtS-hiQOS08lKfa1nWqw","index":"address"}],"type":"search_phase_execution_exception","reason":"all
shards
failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"address","node":"G_1M-1l6SOyy7YHWBk2SSQ","reason":{"type":"query_shard_exception","reason":"failed
to create query: {\n \"bool\" : {\n \"filter\" : [\n {\n
\"term\" : {\n \"root\" : {\n \"value\" : true,\n
\"boost\" : 1.0\n }\n }\n },\n {\n
\"nested\" : {\n \"query\" : {\n \"term\" : {\n
\"parts.aoGuid\" : {\n \"value\" :
\"2d598ce8-feaf-4fb0-9320-bcad370a5d52\",\n \"boost\" :
1.0\n }\n }\n },\n \"path\" : \"parts\",\n \"ignore_unmapped\" : false,\n
\"score_mode\" : \"none\",\n \"boost\" : 1.0\n }\n
}\n ],\n \"adjust_pure_negative\" : true,\n \"boost\" : 1.0\n
}\n}","index_uuid":"jqAtS-hiQOS08lKfa1nWqw","index":"address","caused_by":{"type":"illegal_state_exception","reason":"[nested]
nested object under path [parts] is not of nested
type"}}}]},"status":400} at
org.elasticsearch.client.RestClient.convertResponse(RestClient.java:253)
~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestClient.performRequest(RestClient.java:231)
~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestClient.performRequest(RestClient.java:205)
~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at
org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1454)
~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] ... 32
common frames omitted
我该如何解决这个问题?
检查你的索引模板是不是嵌套类型的部分字段?
如果可以 post 你的模板会很棒。
我想我可以通过编写自定义查询来解决问题:
@Query("{\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" {\n" +
" \"match\": {\n" +
" \"parts.aoGuid\": \"?1\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"query_string\": {\n" +
" \"query\": \"?0\",\n" +
" \"fields\": [\n" +
" \"root\"\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}")
List<Address> findByRootAndAoGuidInParts(boolean root, String aoguid);
我有 elasticSearch 7.4。我有一个 Address 模型和类型为 Entry:
的嵌套模型 'parts'@Document(indexName = "address", createIndex = true)
public class Address {
@Id
@Field(type = FieldType.Text, store = true)
public String id;
@Field(type = FieldType.Text)
private String fullAddress;
private String regionCode;
private boolean customQuery = true;
private boolean root;
@Field(type = FieldType.Nested, store = true)
private List<Entry> parts;
@Field(type = FieldType.Nested, store = true)
private House house;
}
public class Entry {
private String aoid;
private String aoGuid;
private String code;
private String offName;
private String parentGuid;
private String shortName;
@Field(type = FieldType.Integer)
private Integer aoLevel;
private String postalCode;
}
我想在条目列表的 AoGuid 字段上编写搜索:
@Override
public List<Address> findForHouse(String aoguid) {
SearchSourceBuilder builder = new SearchSourceBuilder();
NestedQueryBuilder findByparts = nestedQuery(
"parts",
termQuery("parts.aoGuid", aoguid),
ScoreMode.None);
TermQueryBuilder findByRoot = termQuery("root", true);
QueryBuilder findByIdAndLocation = QueryBuilders.boolQuery()
.filter(findByRoot)
.filter(findByparts);
builder.query(findByIdAndLocation);
String[] strings = new String[]{"address"};
SearchRequest request = new SearchRequest(strings, builder);
try {
restHighLevelClient.search(request, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
当我调用搜索方法时,出现错误:
org.elasticsearch.ElasticsearchStatusException: Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed] at org.elasticsearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:177) ~[elasticsearch-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:1727) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:1704) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1467) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1424) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1394) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:930) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] at ru.evolenta.server.service.elastic.impl.ElasticQueryAddressServiceImpl.findForHouse(ElasticQueryAddressServiceImpl.java:117) ~[classes/:na] at ru.evolenta.server.service.async.impl.AsyncHouseElasticServiceImpl.lambda$saveFias(AsyncHouseElasticServiceImpl.java:45) ~[classes/:na] at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[na:1.8.0_201] at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_201] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_201] at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291) ~[na:1.8.0_201] at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) ~[na:1.8.0_201] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_201] at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401) ~[na:1.8.0_201] at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734) ~[na:1.8.0_201] at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160) ~[na:1.8.0_201] at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174) ~[na:1.8.0_201] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) ~[na:1.8.0_201] at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) ~[na:1.8.0_201] at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583) ~[na:1.8.0_201] at ru.evolenta.server.service.async.impl.AsyncHouseElasticServiceImpl.saveFias(AsyncHouseElasticServiceImpl.java:42) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke[=12=](AsyncExecutionInterceptor.java:115) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE] at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) ~[na:1.8.0_201] at java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:1.8.0_201] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_201] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_201] at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_201] Suppressed: org.elasticsearch.client.ResponseException: method [POST], host [http://localhost:9200], URI [/address/_search?typed_keys=true&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=query_then_fetch&batched_reduce_size=512&ccs_minimize_roundtrips=true], status line [HTTP/1.1 400 Bad Request] {"error":{"root_cause":[{"type":"query_shard_exception","reason":"failed to create query: {\n \"bool\" : {\n \"filter\" : [\n {\n
\"term\" : {\n \"root\" : {\n \"value\" : true,\n \"boost\" : 1.0\n }\n }\n },\n {\n
\"nested\" : {\n \"query\" : {\n \"term\" : {\n
\"parts.aoGuid\" : {\n \"value\" : \"2d598ce8-feaf-4fb0-9320-bcad370a5d52\",\n \"boost\" : 1.0\n }\n }\n },\n \"path\" : \"parts\",\n \"ignore_unmapped\" : false,\n
\"score_mode\" : \"none\",\n \"boost\" : 1.0\n }\n
}\n ],\n \"adjust_pure_negative\" : true,\n \"boost\" : 1.0\n }\n}","index_uuid":"jqAtS-hiQOS08lKfa1nWqw","index":"address"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"address","node":"G_1M-1l6SOyy7YHWBk2SSQ","reason":{"type":"query_shard_exception","reason":"failed to create query: {\n \"bool\" : {\n \"filter\" : [\n {\n
\"term\" : {\n \"root\" : {\n \"value\" : true,\n \"boost\" : 1.0\n }\n }\n },\n {\n
\"nested\" : {\n \"query\" : {\n \"term\" : {\n
\"parts.aoGuid\" : {\n \"value\" : \"2d598ce8-feaf-4fb0-9320-bcad370a5d52\",\n \"boost\" : 1.0\n }\n }\n },\n \"path\" : \"parts\",\n \"ignore_unmapped\" : false,\n
\"score_mode\" : \"none\",\n \"boost\" : 1.0\n }\n
}\n ],\n \"adjust_pure_negative\" : true,\n \"boost\" : 1.0\n }\n}","index_uuid":"jqAtS-hiQOS08lKfa1nWqw","index":"address","caused_by":{"type":"illegal_state_exception","reason":"[nested] nested object under path [parts] is not of nested type"}}}]},"status":400} at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:253) ~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:231) ~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:205) ~[elasticsearch-rest-client-7.4.0.jar:7.4.0] at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1454) ~[elasticsearch-rest-high-level-client-7.4.0.jar:7.4.0] ... 32 common frames omitted
我该如何解决这个问题?
检查你的索引模板是不是嵌套类型的部分字段? 如果可以 post 你的模板会很棒。
我想我可以通过编写自定义查询来解决问题:
@Query("{\n" +
" \"bool\": {\n" +
" \"must\": [\n" +
" {\n" +
" \"match\": {\n" +
" \"parts.aoGuid\": \"?1\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"query_string\": {\n" +
" \"query\": \"?0\",\n" +
" \"fields\": [\n" +
" \"root\"\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}")
List<Address> findByRootAndAoGuidInParts(boolean root, String aoguid);