Ich bin Neuling in ES und suche auf einem Datensatz von 100k Daten. Hier ist meine Mapping und JSON Einstellung, mit denen ich meine Daten indiziert:ElasticSearch Query Optimierung - 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
}
}
}
}
Ich brauche Dokumente auf allen Feldern Abfrage basierend erwähnt nach einer bestimmten Priorität. Hier ist meine Abfrage nach allen Datensätzen zu suchen.
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();
Die Abfrage tut mir bei der Suche Daten helfen und funktioniert gut, aber mein Problem ist, dass es viel Zeit in Anspruch nimmt, da ich Wildcard Abfrage verwende. Kann jemand bitte helfen, diese Abfrage zu optimieren, oder mir bei der Suche nach der am besten geeigneten Suchanfrage für meine Suche helfen? TIA.
Warum verwenden Sie in erster Linie Platzhalter? Wenn Sie einen Ngram-Tokenizer mit 3+ verwenden, sollte eine normale Übereinstimmungsabfrage mit Eingaben funktionieren, die länger als 2 Zeichen sind. Oder was ist der Grund für den Ngram Tokenizer überhaupt? Eine Nebenbemerkung; Mit diesem Analysator (wie definiert) werden Ihre Abfragen zwischen Groß- und Kleinschreibung unterschieden. Möglicherweise beabsichtigt, aber ziemlich ungewöhnlich. – Slomo
Dank @Slomo Sie haben Recht. Ich hätte keine Wildcards mit Ngram verwenden sollen. kann ich es case insensitive machen? und mit Ngram sollte ich mit term Query oder Match abfragen, was ist der optimale Weg? Entschuldigung, wenn das keine vernünftige Frage ist :) – DivyaMenon