我是ES新手,正在搜索100k数据的记录集。 这里是我的映射和设置JSON与我所收录我的数据:ElasticSearch查询优化 - Java API
setings.json
{
"index": {
"analysis": {
"tokenizer": {
"ngram_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 10
}
},
"analyzer": {
"ngram_tokenizer_analyzer": {
"type": "custom",
"tokenizer": "ngram_tokenizer"
}
}
}
}
}
mappings.json
{
"product": {
"properties": {
"name": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"description": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"vendorModelNumber": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"brand": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"specifications": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"upc": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"storeSkuId": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
},
"modelNumber": {
"type": "string",
"analyzer": "ngram_tokenizer_analyzer",
"store": true
}
}
}
}
我需要查询基于所有域的文档根据一些优先级提到。这是我的查询来搜索所有记录。
BoolQueryBuilder query = QueryBuilders.boolQuery();
int boost = 7;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("name", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("description", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("modelNumber", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("vendorModelNumber", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("storeSkuId", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("upc", "*" + str.toLowerCase() + "*").boost(boost));
}
boost--;
for (String str : dataSplit) {
query.should(QueryBuilders.wildcardQuery("brand", "*" + str.toLowerCase() + "*").boost(boost));
}
client.prepareSearch(index).setQuery(query).setSize(200).setExplain(true).execute().actionGet();
查询确实帮助我在搜索数据和工作正常,但我的问题是,它需要大量的时间,因为我使用通配符查询。 有人可以帮助优化此查询或指导我为我的搜索找到最合适的查询吗? TIA。
为什么你首先使用通配符查询?拥有3+的ngram标记器,普通匹配查询应该能够处理超过2个字符的输入。或者ngram tokenizer的原因是什么?一个旁注;使用此分析器(如定义),您的查询将区分大小写。可能有意,但很不寻常。 – Slomo
谢谢@Slomo你是对的。我不应该用ngram使用通配符。我可以让它不区分大小写吗?和ngram我应该查询与术语查询或匹配这是更优化的方式?对不起,如果这不是一个明智的问题:) – DivyaMenon