簡體   English   中英

ElasticSearch查詢優化-Java API

[英]ElasticSearch query optimization - Java API

我是ES的新手,正在搜索10萬條記錄集。 這是我為數據建立索引的映射和設置JSON:

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。

首先,讓我首先回答一個簡單的問題:處理大小寫。 如果定義自定義分析器,則可以添加不同的過濾器,這些過濾器將在令牌化程序處理完輸入應用於每個令牌。

{
"index": {
    "analysis": {
        "tokenizer": {
            "ngram_tokenizer": {
                "type": "ngram",
                "min_gram": 3,
                "max_gram": 10
            }
        },
        "analyzer": {
            "ngram_tokenizer_analyzer": {
                "type": "custom",
                "tokenizer": "ngram_tokenizer",
                "filter": [
                    "lowercase",
                    ...
                ]
            }
        }
    }
}

如您所見,有一個現有的小寫過濾器,它將簡單地將所有標記轉換為小寫。 我強烈建議參考文檔 這些令牌過濾器很多


現在更復雜的部分:NGram標記器。 同樣,為了更深入地理解,您可能需要閱讀docs 但是提到您的問題時,您的令牌生成器實際上將創建長度為3到10的項。這意味着文本

I am an example TEXT.

基本上會創建很多令牌。 只是顯示一些:

  • 大小3:“ I a”,“ am”,“ am”,...,“ TEX”,“ EXT”
  • 大小4:“我是”,“我”,“我是”,...,“ TEX”,“ TEXT”。
  • 大小10:“我是前任”,...

你明白了。 小寫的令牌過濾器現在將小寫這些令牌)

匹配查詢和術語查詢之間的區別:分析匹配查詢,但不分析術語查詢。 實際上,這意味着您的匹配查詢可以匹配多個詞。 例如:您匹配exam"

這將匹配實際上3個方面: exaxamexam

這對比賽的分數有影響。 比賽越多,得分越高。 在某些情況下是期望的,在其他情況下則是不希望的。

不分析詞條查詢,這意味着exam會匹配,但只會匹配一個詞條(當然是exam )。 但是,由於沒有對其進行分析,因此也沒有將其小寫,這意味着您必須自己編寫代碼。 Exam永遠不會匹配,因為如果您使用小寫的令牌過濾器,則索引中不會包含大寫字母的詞。

不確定您的用例。 但是我有一種感覺,您可以(甚至想要)確實使用術語查詢。 但是請注意,索引中沒有大小大於10的術語。因為這就是您的ngram-tokenizer所做的。

/編輯:

關於匹配查詢,以及需要使用術語的原因,需要指出一些事情:一些Simple匹配查詢(例如Simple也可以匹配example中的mple

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM