elasticsearch Elastic中的查询构建- Java

zazmityj  于 2022-11-02  发布在  ElasticSearch
关注(0)|答案(1)|浏览(265)

我有一个在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);
    }
jchrr9hc

jchrr9hc1#

我刚刚使用Spring Data Elasticsearch 4.4.5和您的类LocationSearchLocationTypeSearch运行了一个应用程序测试,只是发送一个查询看看是否失败,不存储任何数据并检查结果。我对此没有任何问题。
我在LocationSearch类中添加了@Document注解来定义要使用的索引,并删除了parentLocation,因为我没有相应的类:

@Document(indexName = "location-search")
public class LocationSearch {
    // ...
}

在测试中我调用

operations.indexOps(LocationSearch.class).createWithMapping();
  operations.search(autoCompleteLocationQueryBuilder("pur", "1", 42L), LocationSearch.class);

第一个调用创建索引并写入索引Map。在定义Map函数的地方,索引Map并不重要,可以通过Spring Data Elasticsearch在新索引上创建Map,调用如上所示。Spring Data Elasticsearch将查看属性上的注解(@Field@MultiField等)并创建Map,在本例中为:

{
  "location-search": {
    "mappings": {
      "properties": {
        "_class": {
          "doc_values": false,
          "index": false,
          "type": "keyword"
        },
        "code": {
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "type": "text"
        },
        "location-id": {
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "type": "text"
        },
        "locationType": {
          "properties": {
            "_class": {
              "doc_values": false,
              "index": false,
              "type": "keyword"
            },
            "level": {
              "type": "integer"
            },
            "name": {
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              },
              "type": "text"
            }
          },
          "type": "nested"
        },
        "name": {
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "type": "text"
        },
        "tenant-id": {
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "type": "text"
        }
      }
    }
  }
}

您可以呼叫 /<INDEX_NAME>/_mappings 来撷取这个Map。请注意,Map会定义locationType字段的巢状型别。
由Spring Data Elasticsearch创建的搜索如下所示:

{
    "from": 0,
    "size": 10,
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "tenantId": {
                            "query": 42,
                            "operator": "OR",
                            "prefix_length": 0,
                            "max_expansions": 50,
                            "fuzzy_transpositions": true,
                            "lenient": false,
                            "zero_terms_query": "NONE",
                            "auto_generate_synonyms_phrase_query": true,
                            "boost": 1.0
                        }
                    }
                },
                {
                    "regexp": {
                        "name": {
                            "value": ".*pur*",
                            "flags_value": 255,
                            "max_determinized_states": 10000,
                            "boost": 1.0
                        }
                    }
                },
                {
                    "nested": {
                        "query": {
                            "bool": {
                                "must": [
                                    {
                                        "match": {
                                            "locationType.level": {
                                                "query": "1",
                                                "operator": "OR",
                                                "prefix_length": 0,
                                                "max_expansions": 50,
                                                "fuzzy_transpositions": true,
                                                "lenient": false,
                                                "zero_terms_query": "NONE",
                                                "auto_generate_synonyms_phrase_query": true,
                                                "boost": 1.0
                                            }
                                        }
                                    }
                                ],
                                "adjust_pure_negative": true,
                                "boost": 1.0
                            }
                        },
                        "path": "locationType",
                        "ignore_unmapped": false,
                        "score_mode": "avg",
                        "boost": 1.0
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1.0
        }
    },
    "version": true,
    "explain": false
}

这基本上与您为查询显示的内容相同,它只包含了Elasticsearch客户端库添加的查询中发送的一些默认值。
但是,这个查询不会像您的情况那样失败。
所以我认为索引的Map没有包含正确的嵌套定义。

GET /dev_skp_location/_mappings

如果巢状字段Map正确,则会传回-这也是您从应用程序存取的索引吗?
有关Map的详细信息,请查看the Elasticsearch documentation

相关问题