Nachdem ich Elasticsearch und Go gelernt hatte, erstellte ich eine Such-API und fasste die Probleme bei der Verwendung und Konfiguration der Ergebnisse zusammen.
Ausführungsumgebung https://github.com/takenoko-gohan/castle-search-api-environment Such-API https://github.com/takenoko-gohan/castle-search-api
In der Umgebungskonstruktion werden Docker und Docker-Compose verwendet.
git clone https://github.com/takenoko-gohan/castle-search-api-environment.git
cd castle-search-api-environment
docker-compose build --no-cache
docker-compose up -d
#Bitte führen Sie nach einer Weile nach dem Start von elasticsearch aus
sh es/script/es_init.sh
Stellen Sie bei Verwendung der Such-API eine Anfrage in der folgenden Form. Der Abfrageparameter "Schlüsselwort" gibt das Schlüsselwort bei der Suche an. Geben Sie im Abfrageparameter "Präfektur" die Präfektur an, die Sie eingrenzen möchten. Der folgende Befehl sucht nach Burgen, deren Präfektur "Fukushima" ist und das Schlüsselwort "Tsuruga Castle" enthält.
curl -XGET "http://localhost:8080/search?keyword=Tsuruga Schloss&prefecture=Präfektur Fukushima"
Elasticsearch
Der Index wurde wie folgt eingestellt. Zum Zeitpunkt der Suche und des Index verwendet der Analysator den Suchmodus, wenn er in Token unterteilt wird, löscht Teile mit Hilfswörtern, Hilfsverben, Satzzeichen und Lesepunkten und setzt das Token so, dass es in SudachiNormalizedFormAttribute geändert wird.
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0,
"analysis": {
"tokenizer": {
"sudachi_tokenizer": {
"type": "sudachi_tokenizer",
"split_mode": "C",
"discard_punctuation": true,
"resources_path": "/usr/share/elasticsearch/config/sudachi",
"settings_path": "/usr/share/elasticsearch/config/sudachi/sudachi.json"
}
},
"analyzer": {
"sudachi_analyzer": {
"filter": [
"my_searchfilter",
"my_posfilter",
"sudachi_normalizedform"
],
"tokenizer": "sudachi_tokenizer",
"type": "custom"
}
},
"filter":{
"my_searchfilter": {
"type": "sudachi_split",
"mode": "search"
},
"my_posfilter":{
"type":"sudachi_part_of_speech",
"stoptags":[
"Partikel",
"Hilfsverb",
"Hilfssymbol,Phrase",
"Hilfssymbol,Lesepunkt"
]
}
}
}
}
}
}
Die Indexzuordnung ist wie folgt.
Feld | Art | Bemerkungen |
---|---|---|
name | text | Name des Schlosses |
prefectures | keyword | Präfekturen |
rulers | text | Schlossbesitzer |
description | text | Überblick über die Burg |
{
"properties": {
"name": {"type" : "text", "analyzer": "sudachi_analyzer"},
"prefecture": {"type": "keyword"},
"rulers": {"type": "text", "analyzer": "sudachi_analyzer"},
"description": {"type": "text", "analyzer": "sudachi_analyzer"}
}
}
Der Suchindex ist Wikipedia "[Kategorie: 100 berühmte Schlösser in Japan](https://ja.wikipedia.org/wiki/Category:%E6%97%A5%E6%9C%AC100%E5%90%8D%E5" Die basierend auf "% 9F% 8E)" erstellten Daten werden eingefügt.
Die Such-API ist das Go-Sprachframework "echo" und der Elastic Search-Client "go-elasticsearch". Ich habe es mit erstellt. Die API erleichtert das Erstellen und Ausführen einer Abfrage an Elasticsearch basierend auf den zuerst empfangenen Parametern und das Antworten auf den Client wie bei jedem Feld des Dokuments, das die Suche getroffen hat.
Bei der Suche mit dem Abfrageparameter "Schlüsselwort" wird die Punktzahl in der Reihenfolge "Name> Lineale> Beschreibung" mit Boost gewichtet. Bei der Suche mit dem Abfrageparameter "Präfektur" versuchen wir, eine exakte Übereinstimmungssuche für das Feld "Präfektur" durchzuführen.
package search
func createQuery(q *Query) map[string]interface{} {
query := map[string]interface{}{}
if q.Keyword != "" && q.Prefecture != "" {
query = map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"bool": map[string]interface{}{
"should": []map[string]interface{}{
{
"match": map[string]interface{}{
"name": map[string]interface{}{
"query": q.Keyword,
"boost": 3,
},
},
},
{
"match": map[string]interface{}{
"rulers": map[string]interface{}{
"query": q.Keyword,
"boost": 2,
},
},
},
{
"match": map[string]interface{}{
"description": map[string]interface{}{
"query": q.Keyword,
"boost": 1,
},
},
},
},
"minimum_should_match": 1,
},
},
{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"term": map[string]interface{}{
"prefecture": q.Prefecture,
},
},
},
},
},
},
},
},
}
} else if q.Keyword != "" && q.Prefecture == "" {
query = map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"should": []map[string]interface{}{
{
"match": map[string]interface{}{
"name": map[string]interface{}{
"query": q.Keyword,
"boost": 3,
},
},
},
{
"match": map[string]interface{}{
"rulers": map[string]interface{}{
"query": q.Keyword,
"boost": 2,
},
},
},
{
"match": map[string]interface{}{
"description": map[string]interface{}{
"query": q.Keyword,
"boost": 1,
},
},
},
},
"minimum_should_match": 1,
},
},
}
} else if q.Keyword == "" && q.Prefecture != "" {
query = map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
{
"term": map[string]interface{}{
"prefecture": q.Prefecture,
},
},
},
},
},
}
}
return query
}
Als ich den Vorgang nach dem Erstellen vorerst überprüfte, erhielt ich die folgende Antwort.
curl -XGET "http://localhost:8080/search?keyword=Wakamatsu Schloss&prefectures=Präfektur Fukushima"
{
"message": "Die Suche war erfolgreich.",
"Results": [
{
"name": "Wakamatsu Schloss",
"prefecture": "Präfektur Fukushima",
"rulers": [
"Herr Gamo, Herr Uesugi, Herr Kato, Herr Hoshina, Matsudaira Aizu"
],
"description": "Das Wakamatsu Castle befindet sich in 1 Pursuit Town, Aizu Wakamatsu City, Präfektur Fukushima.-Es ist eine japanische Burg, die in 1 war. Es wird in der Umgebung allgemein als Tsurugajo bezeichnet und außerhalb der Region häufig als Aizu Wakamatsu Castle bezeichnet. In der Literaturgeschichte wird es manchmal als Kurokawa Castle oder Aizu Castle bezeichnet. Als nationale historische Stätte trägt sie den Namen Wakamatsu Castle Ruins."
},
{
"name": "Nihonmatsu Schloss",
"prefecture": "Präfektur Fukushima",
"rulers": [
"Herr Kato",
"Herr Niwa",
"Herr Gamo",
"Herr Nihonmatsu",
"Herr Uesugi",
"Mr. Date"
],
"description": "Nihonmatsujo ist eine japanische Burg (Hirayama Castle) in Guo, Stadt Nihonmatsu, Präfektur Fukushima. Eine der 100 berühmten Burgen Japans. Auch bekannt als Kasumiga Castle und Shirahata Castle. Am 26. Juli 2007 wurde es als nationale historische Stätte als Stätte der Burg Nihonmatsu ausgewiesen. Es wurde als "Kasumigajo Park" als einer der 100 besten Aussichtspunkte für Kirschblüten in Japan ausgewählt."
},
{
"name": "Shirakawa Komine Schloss",
"prefecture": "Präfektur Fukushima",
"rulers": [
"Herr Matsudaira",
"Herr Niwa",
"Herr Yuki Shirakawa",
"Herr Gamo",
"Herr Abe_(Tokugawa Fuyo)"
],
"description": "Das Shirakawa Komine Castle ist ein japanisches Schloss in der Stadt Shirakawa in der Präfektur Fukushima (Shirakawa, Shirakawa-gun, Rikuokukoku). Auch einfach Shirakawa Castle oder Komine Castle genannt. Es ist als nationale historische Stätte ausgewiesen. Darüber hinaus ist es eine der 100 berühmten Burgen in Japan."
}
]
}
Die Suchergebnisse gingen davon aus, dass nur die Burg Wakamatsu getroffen werden würde, aber auch andere Burgen in der Präfektur Fukushima. Als ich überprüfte, wie der folgende Befehl analysiert wurde, scheint Wakamatsu Castle durch "Wakamatsu / Castle" geteilt zu sein. Daher scheinen auch andere Burgen von der "Burg" getroffen worden zu sein, die zum Zeitpunkt der Suche separat geschrieben wurde.
curl -XGET 'http://localhost:9200/castle/_analyze?pretty' -H 'Content-Type: application/json' -d '
{
"text": "Wakamatsu Schloss",
"analyzer": "sudachi_analyzer"
}'
{
"tokens" : [
{
"token" : "Wakamatsu",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0
},
{
"token" : "Schloss",
"start_offset" : 2,
"end_offset" : 3,
"type" : "word",
"position" : 1
}
]
}
Erstellen Sie daher unter Bezugnahme auf diesen Artikel eine CSV-Datei im folgenden Format und erstellen Sie ein Benutzerwörterbuch, in dem die Namen der einzelnen Schlösser im Analysegerät aufgeführt sind. Hat sich registriert.
Wakamatsu Schloss,4786,4786,5000,Wakamatsu Schloss,Substantiv,固有Substantiv,Allgemeines,*,*,*,Wakamatsujo,Wakamatsu Schloss,*,*,*,*,*
Nachdem ich mich im Benutzerwörterbuch registriert hatte, überprüfte ich die Analyseergebnisse, aber diesmal wurde es die richtige Nomenklatur "Wakamatsu Castle".
curl -XGET 'http://localhost:9200/castle/_analyze?pretty' -H 'Content-Type: application/json' -d '
{
"text": "Wakamatsu Schloss",
"analyzer": "sudachi_analyzer"
}'
{
"tokens" : [
{
"token" : "Wakamatsu Schloss",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0
}
]
}
Als ich erneut mit der Such-API suchte, traf nur Wakamatsu Castle wie erwartet.
curl -XGET "http://localhost:8080/search?keyword=Wakamatsu Schloss&prefecture=Präfektur Fukushima"
{
"message": "Die Suche war erfolgreich.",
"Results": [
{
"name": "Wakamatsu Schloss",
"prefecture": "Präfektur Fukushima",
"rulers": [
"Herr Gamo, Herr Uesugi, Herr Kato, Herr Hoshina, Matsudaira Aizu"
],
"description": "Das Wakamatsu Castle befindet sich in 1 Pursuit Town, Aizu Wakamatsu City, Präfektur Fukushima.-Es ist eine japanische Burg, die in 1 war. Es wird in der Umgebung allgemein als Tsurugajo bezeichnet und außerhalb der Region häufig als Aizu Wakamatsu Castle bezeichnet. In der Literaturgeschichte wird es manchmal als Kurokawa Castle oder Aizu Castle bezeichnet. Als nationale historische Stätte trägt sie den Namen Wakamatsu Castle Ruins."
}
]
}
Es trat jedoch ein anderes Problem auf. Dieses Mal, als ich in Wakamatsu und in der Präfektur Fukushima nach Schlüsselwörtern suchte, wurden keine Treffer gefunden. Durch die Registrierung des Benutzerwörterbuchs scheint Wakamatsu Castle nicht getroffen zu haben, da es nicht mehr durch "Wakamatsu / Castle" geteilt wurde.
curl -XGET "http://localhost:8080/search?keyword=Wakamatsu&prefecture=Präfektur Fukushima"
{
"message": "Die Suche war erfolgreich.",
"Results": null
}
Laut hier können Informationen zur Aufteilung in A-Einheiten in der 16. Spalte der CSV-Datei beschrieben werden. ist. Daher habe ich die CSV-Datei in der folgenden Form so geändert, dass sie im Suchmodus in C-Einheiten und A-Einheiten unterteilt werden kann. (Nur Wakamatsu Castle, Nihonmatsu Castle und Shirakawa Komine Castle ...)
Wakamatsu Schloss,4786,4786,5000,Wakamatsu Schloss,Substantiv,固有Substantiv,Allgemeines,*,*,*,Wakamatsujo,Wakamatsu Schloss,*,C,650091/368637,*,*
Nihonmatsu Schloss,4786,4786,5000,Nihonmatsu Schloss,Substantiv,固有Substantiv,Allgemeines,*,*,*,Japanischer Matsujo,Nihonmatsu Schloss,*,C,281483/368637,*,*
Shirakawa Komine Schloss,4786,4786,5000,Shirakawa Komine Schloss,Substantiv,固有Substantiv,Allgemeines,*,*,*,Shirakawa Kominejo,Shirakawa Komine Schloss,*,C,584799/394859/368637,*,*
curl -XGET 'http://localhost:9200/castle/_analyze?pretty' -H 'Content-Type: application/json' -d '
{
"text": "Wakamatsu Schloss",
"analyzer": "sudachi_analyzer"
}'
{
"tokens" : [
{
"token" : "Wakamatsu Schloss",
"start_offset" : 0,
"end_offset" : 3,
"type" : "word",
"position" : 0,
"positionLength" : 2
},
{
"token" : "Wakamatsu",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0
},
{
"token" : "Schloss",
"start_offset" : 2,
"end_offset" : 3,
"type" : "word",
"position" : 1
}
]
}
Selbst wenn Sie in Wakamatsu und in der Präfektur Fukushima nach Schlüsselwörtern suchen, wird Wakamatsu Castle ein Hit. Es ist schwer, die gewünschte Suche zu finden.
curl -XGET "http://localhost:8080/search?keyword=Wakamatsu Schloss&prefecture=Präfektur Fukushima"
{
"message": "Die Suche war erfolgreich.",
"Results": [
{
"name": "Wakamatsu Schloss",
"prefecture": "Präfektur Fukushima",
"rulers": [
"Herr Gamo, Herr Uesugi, Herr Kato, Herr Hoshina, Matsudaira Aizu"
],
"description": "Das Wakamatsu Castle befindet sich in 1 Pursuit Town, Aizu Wakamatsu City, Präfektur Fukushima.-Es ist eine japanische Burg, die in 1 war. Es wird in der Umgebung allgemein als Tsurugajo bezeichnet und außerhalb der Region häufig als Aizu Wakamatsu Castle bezeichnet. In der Literaturgeschichte wird es manchmal als Kurokawa Castle oder Aizu Castle bezeichnet. Als nationale historische Stätte trägt sie den Namen Wakamatsu Castle Ruins."
}
]
}
Praktisch zum Erstellen eines Benutzerwörterbuchs mit Elasticsearch + Sudachi + Docker So erstellen Sie ein Sudachi-Benutzerwörterbuch elasticsearch-sudachi README go-elasticsearch README