我有一个在Kibana中运行得很好的弹性查询,并且我得到了想要的结果。但是当我尝试通过Java使用QueryBuilders构建查询来运行它时,API不工作,并给出以下错误。
Suppressed: org.elasticsearch.client.ResponseException: method [POST], host [http://localhost:9200], URI [/dev_skp_location/_search?typed_keys=true&max_concurrent_shard_requests=5&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true&ignore_throttled=true&search_type=dfs_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: [nested] nested object under path [locationType] is not of nested type","index_uuid":"0nzK09YiRqmu-s9z_Um0SQ","index":"dev_skp_location"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"dev_skp_location","node":"EIOx4chpQF2JDbGeX8Kc9Q","reason":{"type":"query_shard_exception","reason":"failed to create query: [nested] nested object under path [locationType] is not of nested type","index_uuid":"0nzK09YiRqmu-s9z_Um0SQ","index":"dev_skp_location","caused_by":{"type":"illegal_state_exception","reason":"[nested] nested object under path [locationType] is not of nested type"}}}]},"status":400}
at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:326)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:296)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:270)
at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1654)
"reason": "action [cluster:monitor/state] is unauthorized for user [skp_dev] with roles [skp_dev], this action is granted by the cluster privileges [read_ccr,transport_client,manage_ccr,monitor,manage,all]"
这是我在Kibana上工作的弹性查询,我试图获取的是名称中有“pur”且位置类型级别为1的位置。
GET dev_skp_location/_search
{
"query": {
"bool":{
"must":[
{
"regexp": { "name": ".*pur*"}
},
{
"nested": {
"path": "locationType",
"query": {
"bool": {
"must": [
{
"match": { "locationType.level": "1" }
}]
}
},
"score_mode": "avg"
}
}
]
}
}
}
这是我的查询生成器查询。
public Query AutoCompleteLocationQueryBuilder(String locationTerm, String level, Long tenantId){
QueryBuilder tenantQuery = QueryBuilders
.matchQuery("tenantId", tenantId);
String regexExpression = ".*" + locationTerm + "*";
QueryBuilder regexQuery = QueryBuilders.regexpQuery("name",regexExpression);
String nestedPath="locationType";
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder matchQuery =
QueryBuilders.matchQuery("locationType.level", level);
NestedQueryBuilder nestedQuery = QueryBuilders
.nestedQuery(nestedPath, boolQueryBuilder.must(matchQuery), ScoreMode.Avg);
QueryBuilder finalQuery = QueryBuilders.boolQuery()
.must(tenantQuery)
.must(regexQuery)
.must(nestedQuery);
return new NativeSearchQueryBuilder()
.withQuery(finalQuery)
.build()
.setPageable(PageRequest.of(0, 10));
}
你能帮我吗?就像我犯了什么错误一样?下面是位置的模型。
public class LocationSearch {
@Id
private String id = UUID.randomUUID().toString();
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = { @InnerField(suffix = "keyword", type = FieldType.Keyword) }
)
private String locationId;
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = { @InnerField(suffix = "keyword", type = FieldType.Keyword) }
)
private String name;
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = { @InnerField(suffix = "keyword", type = FieldType.Keyword) }
)
private String code;
@Field(type=FieldType.Nested, name="parentLocation")
private ParentLocationSearch parentLocation;
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = { @InnerField(suffix = "keyword", type = FieldType.Keyword) }
)
private String tenantId;
@Field(type=FieldType.Nested, name="locationType")
private LocationTypeSearch locationType;
}
位置类型搜索的模型
public class LocationTypeSearch {
@Id
private String id;
@MultiField(
mainField = @Field(type = FieldType.Text),
otherFields = { @InnerField(suffix = "keyword", type = FieldType.Keyword) }
)
private String name;
@Field(type=FieldType.Integer)
private String level;
}
还有索引Map功能
@Override
public void indexUserToElasticsearch(Long tenantId, User user) {
if (user == null) {
throw new ResourceNotFoundException(ErrorResponses.USER_IS_NULL);
}
UserSearch userSearch = new UserSearch();
userSearch.setUserId(user.getId().toString());
userSearch.setUserName(user.getUserName());
userSearch.setFirstName(user.getFirstName());
userSearch.setLastName(user.getLastName());
userSearch.setEmail(user.getEmail());
userSearch.setTenantId(tenantId.toString());
this.userSearchRepository.save(userSearch);
}
1条答案
按热度按时间jchrr9hc1#
我刚刚使用Spring Data Elasticsearch 4.4.5和您的类
LocationSearch
和LocationTypeSearch
运行了一个应用程序测试,只是发送一个查询看看是否失败,不存储任何数据并检查结果。我对此没有任何问题。我在
LocationSearch
类中添加了@Document
注解来定义要使用的索引,并删除了parentLocation
,因为我没有相应的类:在测试中我调用
第一个调用创建索引并写入索引Map。在定义Map函数的地方,索引Map并不重要,可以通过Spring Data Elasticsearch在新索引上创建Map,调用如上所示。Spring Data Elasticsearch将查看属性上的注解(
@Field
,@MultiField
等)并创建Map,在本例中为:您可以呼叫 /<INDEX_NAME>/_mappings 来撷取这个Map。请注意,Map会定义
locationType
字段的巢状型别。由Spring Data Elasticsearch创建的搜索如下所示:
这基本上与您为查询显示的内容相同,它只包含了Elasticsearch客户端库添加的查询中发送的一些默认值。
但是,这个查询不会像您的情况那样失败。
所以我认为索引的Map没有包含正确的嵌套定义。
如果巢状字段Map正确,则会传回-这也是您从应用程序存取的索引吗?
有关Map的详细信息,请查看the Elasticsearch documentation