[Elastische Suche x Java] Da das Ausführungsergebnis der in Java erfassten Abfrage von der Annahme abweicht, habe ich → Zusammenfassung der entsprechenden Inhalte untersucht

Bei der Suche mit Elasticsearch in Java wurde das erwartete Ergebnis nicht erzielt, daher habe ich nachgeforscht → geantwortet. Ich werde den Inhalt zusammenfassen.

Umgebung

Umfrage

Quelle

In der Indexdefinition wird der Analysator zusätzlich zur Zuordnungsdefinition wie folgt eingestellt. Die Positionierung des Feldnamens ist wie folgt.

Feldname Datentyp Positionierung
itemId integer Produkt-ID (entspricht dem Primärschlüssel)
itemName text Produktname
itemNameKana text Produktname (Katakana)
itemNameHira text Produktname (Hiragana)

Indexdefinition


{
  "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"
      }
    }
  }
}

Als Prozess auf der Java-Seite wird das eingegebene Suchwort nach Übereinstimmungen in den Feldern Produktname, Produktname (Katakana) oder Produktname (Hiragana) durchsucht und in absteigender Reihenfolge der Punktzahl sortiert. Es ist der Inhalt.

Java-Quellcode


	/**
	 *Produkt Suche
	 *
	 * @param Schlüsselwort Suchwort
	 * @param index index name
	 * @param limit number
	 * @param client Elasticsearch-Verbindungsclient
	 * @Suchergebnisse zurückgeben
	 * @throws IOException
	 */
	public SearchResponse search(String keyword, String index, int limit, RestHighLevelClient client) throws IOException{

		//Suchbedingungen initialisieren
		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);
		//Sortierreihenfolge (nach Punktzahl sortieren)
		searchSourceBuilder.sort(new FieldSortBuilder("_score").order(SortOrder.DESC));
		//Stellen Sie die Anzahl der Retouren ein
		searchBuilder.size(limit);

		SearchRequest request = new SearchRequest(index).source(searchSourceBuilder);

		return client.search(request, RequestOptions.DEFAULT);


	}

Zum Schluss die Ausführungsabfrage in Kibana. Geben Sie das zu suchende Wort an der Stelle ein, an der "Suchwort" eingegeben wurde, und suchen Sie. Geben Sie außerdem 5 für die Größe an (Begrenzung im Java-Quellcode).

Ausführungsabfrage in Kibana


POST item_list/_search
{
  "from": 0,
  "size": 5,
  "sort": {
    "_score": {
      "order": "desc"
    }
  },
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "itemName": "Geben Sie ein Suchwort ein"
           }
        },
        {
          "match": {
            "itemNameKana": "Geben Sie ein Suchwort ein"
          }
        },
        {
          "match": {
            "itemNameHira": "Geben Sie ein Suchwort ein"
          }
        }
      ]
    }
  }
}

Kandidatenfaktoren

Die folgenden Faktoren werden als Kandidatenfaktoren betrachtet.

―― 1. Der Inhalt der in Java ausgegebenen Abfrage ist falsch. ―― 2. Die Einstellungen des Analysators sind falsch. --3. Es ist notwendig, den implizit eingestellten Inhalt zu korrigieren.

Ich beschloss, diese der Reihe nach zu untersuchen.

Durchführung der Umfrage

1. Der Inhalt der in Java ausgegebenen Abfrage ist falsch

Erstens aus der Perspektive, ob der Inhalt der in Java ausgegebenen Abfrage falsch ist. Als Bestätigungsmethode dient der Java-Quellcode SearchRequest request = new SearchRequest(index).source(searchBuilder); In dem in 1 auszuführenden Satz wird ein Haltepunkt gesetzt und der Inhalt von searchSourceBuilder angezeigt.

Der Inhalt war wie folgt.

Inhalt von searchBuilder


{"size"5,"query":{"bool":{"should":[{"match":{"itemName":{"query":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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"}}]}

Auf den ersten Blick scheint es kein Problem zu geben. Das Ausführen dieses Inhalts in Kibana ergab genau das gleiche Ergebnis wie das Ausführen von "Abfrage in Kibana ausführen". Die ausgeführte Abfrage lautet wie folgt.

Abfrage mit dem Inhalt von searchSourceBuilder ausgeführt


POST item_list/_search
{"size"5,"query":{"bool":{"should":[{"match":{"itemName":{"query":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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"}}]}

Aus diesem Ergebnis kann gesagt werden, dass "der Inhalt der in Java ausgegebenen Abfrage falsch ist" nicht die Ursache ist. Als ich zu diesem Zeitpunkt den Score (_score) auf das Erfassungsergebnis in Java überprüfte (Ergebnis zurückgegeben an Elasticsearch → Java: Rückgabewert von client.search (request, RequestOptions.DEFAULT)), Kibana Es stellte sich heraus, dass es sich vom Ausführungsergebnis in unterschied. </ b> (Dies ist ein wichtiger Punkt, der in der Umfrage enthüllt wurde, daher werde ich ihn fett machen.)

2. Die Einstellungen des Analysators sind falsch

Aus der Perspektive, ob die Einstellungen des Analysators falsch sind, sollten Sie bei der Ausführung einer Abfrage in Kibana seltsame Ergebnisse erhalten, wenn die Einstellungen des Analysators falsch sind. Diesmal war es nicht so, also wusste ich, dass "die Einstellungen des Analysators falsch waren" auch nicht die Ursache war.

3. Es ist notwendig, den implizit eingestellten Inhalt zu korrigieren.

Das ist der Rest. Da es keine Probleme mit dem Inhalt von searchSourceBuilder gab, ist dies sehr wahrscheinlich

  • request(SearchRequest)
  • client.search(request, RequestOptions.DEFAULT)(SearchResponse)

Irgendein von.

Als ich den Inhalt der Anfrage (SearchRequest) im Debug-Modus überprüfte,

Inhalt der Anfrage (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":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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":"Geben Sie ein Suchwort ein","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"}}]}}

Es war. Nach der Quelle habe ich es bestätigt, indem ich den Inhalt von searchSourceBuilder überprüft habe, also habe ich es ausgeschlossen.

Wenn es um die wichtigsten Punkte geht,

  • searchType
  • indicesOptions

nicht wahr.

Für searchType:

Es gibt eine Beschreibung in.

Für IndizesOptions,

Ich denke nicht, dass es ein bisschen anders ist, aber

Nicht wahr.

Von diesen wurde der Suchtyp in Bezug auf die Punktzahl (_score) klar angegeben. (Was indicesOptions betrifft, konnte ich nichts über score (_score) finden, soweit ich mich umsah.)

Die oben erwähnte Seite Suchtyp (Elasticsearch-Referenz [6.8]) | elastisch Im Abschnitt "Dfs, Query Then Fetch" von

・ ・ ・ Genauere Bewertung.

Weil es so ist, habe ich beschlossen, dies festzulegen, was eine genauere Punktzahl zu ergeben scheint. (Nach "Korrespondenz")

Korrespondenzinhalt

Aus den Umfrageergebnissen ging hervor, dass es notwendig erscheint, den Inhalt von SearchType zu korrigieren, sodass wir antworten werden. Setzen Sie den searchType von SearchRequest auf "Dfs, Query Then Fetch" (wobei "Additional" geschrieben ist).

Java-Quellcode (nach Änderung)


	/**
	 *Produkt Suche
	 *
	 * @param Schlüsselwort Schlüsselwort
	 * @param index index name
	 * @param limit number
	 * @param client Elasticsearch-Verbindungsclient
	 * @Suchergebnisse zurückgeben
	 * @throws IOException
	 */
	public SearchResponse search(String keyword, String index, int limit, RestHighLevelClient client) throws IOException{

		//Suchbedingungen initialisieren
		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);
		//Sortierreihenfolge (nach Punktzahl sortieren)
		searchSourceBuilder.sort(new FieldSortBuilder("_score").order(SortOrder.DESC));
		//Stellen Sie die Anzahl der Retouren ein
		searchSourceBuilder.size(limit);

		SearchRequest request = new SearchRequest(index).source(searchSourceBuilder);
		//Suchtyp Dfs,Auf Abfrage und dann auf Abrufen setzen//Nachtrag
		request.searchType(SearchType.DFS_QUERY_THEN_FETCH); //Nachtrag
		return client.search(request, RequestOptions.DEFAULT);


	}

Und als ich versuchte, es zu verschieben, war das Ergebnis wie erwartet (genau wie die Ausführungsabfrage in Kibana)! Das Problem ist sicher gelöst! !!

Fazit

Die richtige Antwort war diesmal, den searchType der SearchRequest auf "Dfs, Query Then Fetch" zu setzen. Anfangs war ich ungeduldig, weil ich das erwartete Ergebnis nicht erzielen konnte, aber ich bin froh, dass ich es lösen konnte.

Referenz

Obwohl es nicht im Text erscheint, ist es eine Liste von Artikeln, auf die ich verwiesen habe.

Recommended Posts

[Elastische Suche x Java] Da das Ausführungsergebnis der in Java erfassten Abfrage von der Annahme abweicht, habe ich → Zusammenfassung der entsprechenden Inhalte untersucht
Holen Sie sich das Ergebnis von POST in Java
Zusammenfassung der Punkte, über die ich mir bei der Migration von Java nach Kotlin Sorgen gemacht habe
Der Teil, dem ich in "Einführung in Ajax in Java-Webanwendungen" von NetBeans verfallen war
Ich möchte den Inhalt von Assets in der mit capistrano erstellten Umgebung von Grund auf neu erstellen
Wurde im Basisjahr der Java-Kalenderwoche durchgeführt
Als ich mir Sorgen über statische Methoden in der Java-Oberfläche machte, kam ich zur Reihenfolge der Namensinterpretation