Lorsque j'ai cherché à l'aide d'Elasticsearch en Java, le résultat attendu n'a pas été obtenu, j'ai donc enquêté → répondu. Je vais résumer le contenu.
--Définition d'index
Dans la définition d'index, en plus de la définition des mappages, l'analyseur est également défini comme suit. Le positionnement du nom de champ est le suivant.
Nom de domaine | Type de données | positionnement |
---|---|---|
itemId | integer | ID produit (correspond à la clé primaire) |
itemName | text | Nom du produit |
itemNameKana | text | Nom du produit (Katakana) |
itemNameHira | text | Nom du produit (Hiragana) |
Définition d'index
{
"settings": {
"analysis": {
"filter": {
"my_ngram": {
"type": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"analyzer": {
"my_kuromoji_analyzer": {
"type": "custom",
"tokenizer": "kuromoji_tokenizer",
"char_filter": [
"icu_normalizer",
"kuromoji_iteration_mark"
],
"filter": [
"kuromoji_stemmer",
"my_ngram"
]
}
}
}
},
"mappings": {
"properties": {
"itemId": {
"type": "integer"
},
"itemName": {
"type": "text",
"analyzer": "my_kuromoji_analyzer"
},
"itemNameKana": {
"type": "text",
"analyzer": "my_kuromoji_analyzer"
},
"itemNameHira": {
"type": "text",
"analyzer": "my_kuromoji_analyzer"
}
}
}
}
En tant que processus du côté Java, le mot de recherche saisi est recherché pour toute correspondance dans les champs nom de produit, nom de produit (katakana) ou nom de produit (hiragana), et trié par ordre décroissant de score. C'est le contenu.
Code source Java
/**
*Recherche de produit
*
* @mot de recherche par mot-clé param
* @nom d'index d'index de paramètre
* @nombre limite de paramètre
* @client param client de connexion Elasticsearch
* @renvoyer les résultats de la recherche
* @throws IOException
*/
public SearchResponse search(String keyword, String index, int limit, RestHighLevelClient client) throws IOException{
//Initialiser les conditions de recherche
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.should(QueryBuilders.matchQuery("itemName", keyword))
.should(QueryBuilders.matchQuery("itemNameKana", keyword))
.should(QueryBuilders.matchQuery("itemNameHira", keyword));
searchSourceBuilder.query(boolQueryBuilder);
//Réglage de l'ordre de tri (trier par score)
searchSourceBuilder.sort(new FieldSortBuilder("_score").order(SortOrder.DESC));
//Définissez le nombre de retours
searchBuilder.size(limit);
SearchRequest request = new SearchRequest(index).source(searchSourceBuilder);
return client.search(request, RequestOptions.DEFAULT);
}
Enfin, la requête d'exécution dans Kibana. Entrez le mot que vous souhaitez rechercher à l'endroit où «Rechercher le mot» est entré et recherchez. Spécifiez également 5 pour la taille (limite dans le code source Java).
Requête d'exécution dans Kibana
POST item_list/_search
{
"from": 0,
"size": 5,
"sort": {
"_score": {
"order": "desc"
}
},
"query": {
"bool": {
"should": [
{
"match": {
"itemName": "Entrez un mot de recherche"
}
},
{
"match": {
"itemNameKana": "Entrez un mot de recherche"
}
},
{
"match": {
"itemNameHira": "Entrez un mot de recherche"
}
}
]
}
}
}
Les éléments suivants sont considérés comme des facteurs candidats.
―― 1. Le contenu de la requête émise en Java est incorrect. ―― 2. Les paramètres de l'analyseur sont incorrects.
J'ai décidé d'enquêter sur ces derniers dans l'ordre.
Premièrement, du point de vue de savoir si le contenu de la requête émise en Java est incorrect. Comme méthode de confirmation, le code source Java SearchRequest request = new SearchRequest(index).source(searchBuilder); Vous pouvez voir le contenu de searchSourceBuilder en définissant un point d'arrêt dans la phrase à effectuer.
Le contenu était le suivant.
Contenu de searchBuilder
{"size"5,"query":{"bool":{"should":[{"match":{"itemName":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameKana":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameHira":{"query":"Entrez un mot de recherche","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}},"sort":[{"_score":{"order":"desc"}}]}
À première vue, il ne semble y avoir aucun problème. Lancer ce contenu dans Kibana a donné exactement le même résultat que de cliquer sur "Exécuter la requête dans Kibana". La requête exécutée est la suivante.
Requête exécutée avec le contenu de searchSourceBuilder
POST item_list/_search
{"size"5,"query":{"bool":{"should":[{"match":{"itemName":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameKana":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameHira":{"query":"Entrez un mot de recherche","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}},"sort":[{"_score":{"order":"desc"}}]}
De ce résultat, on peut dire que "le contenu de la requête émise en Java est incorrect" n'est pas la cause. Aussi, lorsque j'ai vérifié le score (_score) à ce stade pour le résultat de l'acquisition en Java (résultat retourné à Elasticsearch → Java: valeur de retour de client.search (request, RequestOptions.DEFAULT)), Kibana Il s'est avéré que c'était différent du résultat de l'exécution. </ b> (C'est un point important qui a été révélé dans l'enquête, je vais donc le mettre en gras)
Ensuite, du point de vue de savoir si les paramètres de l'analyseur sont incorrects, si les paramètres de l'analyseur sont incorrects, vous devriez obtenir des résultats étranges lorsque vous exécutez une requête dans Kibana. Cette fois, ce n'était pas le cas, donc je savais que «les paramètres de l'analyseur étaient erronés» n'était pas non plus la cause.
C'est le reste. Comme il n'y a pas eu de problème avec le contenu de searchSourceBuilder, il est fort possible que
N'importe quel.
Lorsque j'ai vérifié le contenu de la requête (SearchRequest) en mode débogage,
Contenu de la requête (SearchRequest)
SearchRequest{searchType=QUERY_THEN_FETCH, indices=[item_list], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, allowPartialSearchResults=null, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"size":10,"query":{"bool":{"should":[{"match":{"itemName":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameKana":{"query":"Entrez un mot de recherche","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}}},{"match":{"itemNameHira":{"query":"Entrez un mot de recherche","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}},"sort":[{"_score":{"order":"desc"}}]}}
C'était. Après la source, je l'ai confirmé en vérifiant le contenu de searchSourceBuilder, donc je l'ai exclu.
En ce qui concerne, si vous regardez les principaux éléments,
n'est-ce pas.
Pour searchType,
Il y a une description dans.
Pour les indicesOptions,
Je ne pense pas que ce soit un peu différent, mais
N'est-ce pas.
Parmi ceux-ci, le searchType était clairement indiqué en ce qui concerne le score (_score). (En ce qui concerne indicesOptions, je n'ai rien trouvé sur le score (_score) pour autant que j'ai regardé autour de moi.)
La page mentionnée ci-dessus, Type de recherche (Elasticsearch Reference [6.8]) | élastique Dans la section "Dfs, interroger puis récupérer" de
・ ・ ・ Score plus précis.
Parce qu'il y en a, j'ai décidé de définir ceci qui semble donner un score plus précis. (Après "Correspondance")
D'après les résultats de l'enquête, nous avons constaté qu'il semble nécessaire de corriger le contenu de SearchType, nous y répondrons donc. Définissez le searchType de SearchRequest sur "Dfs, Query Then Fetch" (où "Additional" est écrit).
Code source Java (après modification)
/**
*Recherche de produit
*
* @mot-clé param mot-clé
* @nom d'index d'index de paramètre
* @nombre limite de paramètre
* @client param client de connexion Elasticsearch
* @renvoyer les résultats de la recherche
* @throws IOException
*/
public SearchResponse search(String keyword, String index, int limit, RestHighLevelClient client) throws IOException{
//Initialiser les conditions de recherche
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.should(QueryBuilders.matchQuery("itemName", keyword))
.should(QueryBuilders.matchQuery("itemNameKana", keyword))
.should(QueryBuilders.matchQuery("itemNameHira", keyword));
searchSourceBuilder.query(boolQueryBuilder);
//Réglage de l'ordre de tri (trier par score)
searchSourceBuilder.sort(new FieldSortBuilder("_score").order(SortOrder.DESC));
//Définissez le nombre de retours
searchSourceBuilder.size(limit);
SearchRequest request = new SearchRequest(index).source(searchSourceBuilder);
//Type de recherche Dfs,Définir sur Interroger puis récupérer//Postscript
request.searchType(SearchType.DFS_QUERY_THEN_FETCH); //Postscript
return client.search(request, RequestOptions.DEFAULT);
}
Et quand j'ai essayé de le déplacer, le résultat était comme prévu (identique à la requête d'exécution dans Kibana)! Le problème est résolu en toute sécurité! !!
La bonne réponse cette fois était de définir le searchType du SearchRequest sur "Dfs, Query Then Fetch". Au début, j'étais impatient car je ne pouvais pas obtenir le résultat attendu, mais je suis content d'avoir pu le résoudre.
Bien que cela n'apparaisse pas dans le texte, il s'agit d'une liste d'articles auxquels j'ai fait référence.
Recommended Posts