Je suis novice à ES et je recherche sur un ensemble d'enregistrements de 100k données. Voici ma cartographie et la mise en JSON avec lequel j'ai indexé mes données:Optimisation de requête ElasticSearch - API Java
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
}
}
}
}
documents que je dois interroger sur la base de tous les champs mentionné selon une priorité. Voici ma requête pour rechercher tous les enregistrements.
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();
La requête ne me aide dans la recherche de données et fonctionne très bien, mais mon problème est que cela prend beaucoup de temps depuis que je suis en utilisant la requête générique. Est-ce que quelqu'un peut aider à optimiser cette requête ou me guider dans la recherche de la requête la mieux adaptée à ma recherche? TIA.
Pourquoi utilisez-vous les requêtes génériques en premier lieu? Ayant un tokenizer ngram avec 3+, une requête de correspondance normale devrait fonctionner avec des entrées de plus de 2 caractères. Ou quelle est la raison du tokenizer ngram de toute façon? Un sidenote; Avec cet analyseur (tel que défini), vos requêtes seront sensibles à la casse. Peut-être prévu, mais assez inhabituel. – Slomo
Merci @Slomo vous avez raison. Je n'aurais pas dû utiliser des caractères génériques avec ngram. Puis-je le rendre insensible à la casse? et avec ngram je devrais être interroger avec une requête à long terme ou match qui est le moyen le plus optimal? désolé si ce n'est pas une question sensible :) – DivyaMenon