Бързо въвеждане в пълнотекстово търсене с ElasticSearch

Устойчивост отгоре

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА

1. Общ преглед

Пълнотекстови заявки за търсене и извършва езикови търсения срещу документи. Той включва единични или множество думи или фрази и връща документи, които съответстват на условията за търсене.

ElasticSearch е търсачка, базирана на Apache Lucene, безплатна софтуерна библиотека за извличане на информация с отворен код. Той осигурява разпределена, пълнотекстова търсачка с HTTP уеб интерфейс и JSON документи без схеми.

Тази статия разглежда API на ElasticSearch REST и демонстрира основни операции, използващи само HTTP заявки.

2. Настройка

За да инсталирате ElasticSearch на вашето устройство, вижте официалното ръководство за настройка.

RESTfull API работи на порт 9200. Нека тестваме дали работи правилно, като използваме следната команда curl:

curl -XGET '//localhost:9200/'

Ако забележите следния отговор, екземплярът се изпълнява правилно:

{ "name": "NaIlQWU", "cluster_name": "elasticsearch", "cluster_uuid": "enkBkWqqQrS0vp_NXmjQMQ", "version": { "number": "5.1.2", "build_hash": "c8c4c16", "build_date": "2017-01-11T20:18:39.146Z", "build_snapshot": false, "lucene_version": "6.3.0" }, "tagline": "You Know, for Search" }

3. Индексиране на документи

ElasticSearch е ориентиран към документи. Той съхранява и индексира документи. Индексирането създава или актуализира документи. След индексиране можете да търсите, сортирате и филтрирате пълни документи, а не редове от колони с данни. Това е фундаментално различен начин на мислене за данните и е една от причините ElasticSearch да може да извършва сложно пълнотекстово търсене.

Документите са представени като JSON обекти. JSON сериализацията се поддържа от повечето езици за програмиране и се е превърнала в стандартния формат, използван от движението NoSQL. Той е прост, кратък и лесен за четене.

Ще използваме следните произволни записи, за да извършим нашето пълнотекстово търсене:

{ "title": "He went", "random_text": "He went such dare good fact. The small own seven saved man age." } { "title": "He oppose", "random_text": "He oppose at thrown desire of no. \ Announcing impression unaffected day his are unreserved indulgence." } { "title": "Repulsive questions", "random_text": "Repulsive questions contented him few extensive supported." } { "title": "Old education", "random_text": "Old education him departure any arranging one prevailed." }

Преди да можем да индексираме документ, трябва да решим къде да го съхраняваме. Възможно е да има множество индекси, които от своя страна съдържат множество типове. Тези типове съдържат множество документи и всеки документ има множество полета.

Ще съхраняваме документите си по следната схема:

text : Името на индекса.

article : Името на типа.

id : Идентификаторът на този конкретен пример за въвеждане на текст.

За да добавим документ, ще изпълним следната команда:

curl -XPUT 'localhost:9200/text/article/1?pretty' -H 'Content-Type: application/json' -d ' { "title": "He went", "random_text": "He went such dare good fact. The small own seven saved man age." }'

Тук използваме id = 1 , можем да добавим други записи, използвайки същата команда и увеличен id.

4. Извличане на документи

След като добавим всички наши документи, можем да проверим колко документи, като използваме следната команда, имаме в клъстера:

curl -XGET '//localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } }' 

Също така можем да получим документ, използвайки неговия идентификатор със следната команда:

curl -XGET 'localhost:9200/text/article/1?pretty' 

И трябва да получим следния отговор от еластично търсене:

{ "_index": "text", "_type": "article", "_id": "1", "_version": 1, "found": true, "_source": { "title": "He went", "random_text": "He went such dare good fact. The small own seven saved man age." } }

Както виждаме, този отговор съответства на записа, добавен с помощта на id 1.

5. Заявка за документи

Добре, нека извършим пълнотекстово търсене със следната команда:

curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d ' { "query": { "match": { "random_text": "him departure" } } }'

И получаваме следния резултат:

{ "took": 32, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 1.4513469, "hits": [ { "_index": "text", "_type": "article", "_id": "4", "_score": 1.4513469, "_source": { "title": "Old education", "random_text": "Old education him departure any arranging one prevailed." } }, { "_index": "text", "_type": "article", "_id": "3", "_score": 0.28582606, "_source": { "title": "Repulsive questions", "random_text": "Repulsive questions contented him few extensive supported." } } ] } }

Както виждаме, търсим „неговото напускане“ и получаваме два резултата с различни резултати. Първият резултат е очевиден, тъй като текстът има извършеното търсене вътре в него и както виждаме, имаме резултат от 1.4513469 .

Вторият резултат се извлича, защото целевият документ съдържа думата „него“.

По подразбиране ElasticSearch сортира съответстващите резултати по тяхната оценка на релевантност, т.е. по това колко добре всеки документ съответства на заявката. Обърнете внимание, че резултатът от втория резултат е малък спрямо първия удар, което показва по-ниска значимост.

6. Размито търсене

Размитото съвпадение третира две думи, които са „размито“ подобни, сякаш са една и съща дума. Първо, трябва да определим какво имаме предвид под размитост.

Elasticsearch поддържа максимално разстояние за редактиране, посочено с параметъра fuzziness, от 2. Параметърът fuzziness може да бъде зададен на AUTO, което води до следните максимални разстояния за редактиране:

  • 0 за низове от един или два знака
  • 1 за низове от три, четири или пет знака
  • 2 за низове с повече от пет знака

you may find that an edit distance of 2 returns results that don’t appear to be related.

You may get better results, and better performance, with a maximum fuzziness of 1. Distance refers to the Levenshtein distance that is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits.

OK let's perform our search with fuzziness:

curl -XGET 'localhost:9200/text/article/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "random_text": { "query": "him departure", "fuzziness": "2" } } } }'

And here's the result:

{ "took": 88, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 4, "max_score": 1.5834423, "hits": [ { "_index": "text", "_type": "article", "_id": "4", "_score": 1.4513469, "_source": { "title": "Old education", "random_text": "Old education him departure any arranging one prevailed." } }, { "_index": "text", "_type": "article", "_id": "2", "_score": 0.41093433, "_source": { "title": "He oppose", "random_text": "He oppose at thrown desire of no. \ Announcing impression unaffected day his are unreserved indulgence." } }, { "_index": "text", "_type": "article", "_id": "3", "_score": 0.2876821, "_source": { "title": "Repulsive questions", "random_text": "Repulsive questions contented him few extensive supported." } }, { "_index": "text", "_type": "article", "_id": "1", "_score": 0.0, "_source": { "title": "He went", "random_text": "He went such dare good fact. The small own seven saved man age." } } ] } }'

As we can see the fuzziness give us more results.

We need to use fuzziness carefully because it tends to retrieve results that look unrelated.

7. Conclusion

In this quick tutorial we focused on indexing documents and querying Elasticsearch for full-text search, directly via it's REST API.

Ние, разбира се, разполагаме с API за множество езици за програмиране, когато е необходимо, но API все още е доста удобен и езиков агностик.

Устойчивост отдолу

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА