Elasticsearch, Lucene kullanan ve Java ile yazılmış, json rest api'ye sahip bir arama motorudur. Bu motorun tüm avantajlarının bir açıklaması şu adreste mevcuttur: resmi sitesi. Aşağıda Elasticsearch'ü ES olarak anacağız.
Benzer motorlar bir belge veritabanındaki karmaşık aramalar için kullanılır. Örneğin, dilin morfolojisini dikkate alarak arama yapın veya coğrafi koordinatlara göre arama yapın.
Bu yazıda blog yazılarını indeksleme örneğini kullanarak ES'nin temelleri hakkında konuşacağım. Size belgeleri nasıl filtreleyeceğinizi, sıralayacağınızı ve arayacağınızı göstereceğim.
İşletim sistemine bağlı kalmamak adına ES'e olan tüm isteklerimi CURL kullanarak yapacağım. Ayrıca Google Chrome için bir eklenti de var. duyu.
Metin, belgelere ve diğer kaynaklara bağlantılar içerir. Sonunda belgelere hızlı erişim için bağlantılar bulunmaktadır. Bilinmeyen terimlerin tanımlarını şurada bulabilirsiniz: sözlükler.
ES'yi yükleme
Bunu yapmak için öncelikle Java'ya ihtiyacımız var. Geliştiriciler Tavsiye Java 8 güncelleme 20 veya Java 7 güncelleme 55'ten daha yeni Java sürümlerini yükleyin.
# Добавим документ c id 1 типа post в индекс blog.
# ?pretty указывает, что вывод должен быть человеко-читаемым.
curl -XPUT "$ES_URL/blog/post/1?pretty" -d'
{
"title": "Веселые котята",
"content": "<p>Смешная история про котят<p>",
"tags": [
"котята",
"смешная история"
],
"published_at": "2014-09-12T20:44:42+00:00"
}'
ES otomatik olarak oluşturuldu indeks blog ve tip postalamak. Koşullu bir benzetme yapabiliriz: dizin bir veritabanıdır ve tür bu veritabanındaki bir tablodur. Her türün kendi şeması vardır – haritalamatıpkı ilişkisel bir tablo gibi. Belge dizine eklendiğinde eşleme otomatik olarak oluşturulur:
# Получим mapping всех типов индекса blog
curl -XGET "$ES_URL/blog/_mapping?pretty"
ES'nin tek bir değer ile bir değerler dizisi arasında ayrım yapmadığını belirtmekte fayda var. Örneğin, başlık alanı yalnızca bir başlık içerir ve etiketler alanı, eşlemede aynı şekilde temsil edilmelerine rağmen bir dizi dize içerir.
Haritalama hakkında daha sonra daha fazla konuşacağız.
istekler
Bir belgeyi kimliğine göre alma:
# извлечем документ с id 1 типа post из индекса blog
curl -XGET "$ES_URL/blog/post/1?pretty"
Yanıtta yeni anahtarlar ortaya çıktı: _version и _source. Genel olarak ile başlayan tüm tuşlar _ resmi olarak sınıflandırılır.
Anahtar _version belge sürümünü gösterir. İyimser kilitleme mekanizmasının çalışması için buna ihtiyaç var. Örneğin, sürümü 1 olan bir belgeyi değiştirmek istiyoruz. Değiştirilen belgeyi gönderiyoruz ve bunun, sürümü 1 olan bir belgenin düzenlemesi olduğunu belirtiyoruz. Başka biri de sürüm 1 olan bir belgeyi düzenlediyse ve değişiklikleri bizden önce gönderdiyse, o zaman ES değişikliklerimizi kabul etmeyecek çünkü belgeyi sürüm 2 ile saklar.
Anahtar _source indekslediğimiz belgeyi içerir. ES bu değeri arama işlemleri için kullanmaz çünkü Aramak için indeksler kullanılır. ES, yerden tasarruf etmek için sıkıştırılmış bir kaynak belgeyi saklar. Kaynak belgenin tamamına değil de yalnızca kimliğe ihtiyacımız varsa, kaynak depolamayı devre dışı bırakabiliriz.
Ek bilgiye ihtiyacımız yoksa yalnızca _source içeriğini alabiliriz:
curl -XPUT "$ES_URL/blog/post/3" -d'
{
"title": "Как у меня появился котенок",
"content": "<p>Душераздирающая история про бедного котенка с улицы<p>",
"tags": [
"котята"
],
"published_at": "2014-07-21T20:44:42+00:00"
}'
Сортировка
# найдем последний пост по дате публикации и извлечем поля title и published_at
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"size": 1,
"_source": ["title", "published_at"],
"sort": [{"published_at": "desc"}]
}'
Son gönderiyi seçtik. size Düzenlenecek belge sayısını sınırlar. total taleple eşleşen toplam belge sayısını gösterir. sort çıktıda sıralamanın gerçekleştirildiği bir tamsayı dizisi bulunur. Onlar. tarih bir tamsayıya dönüştürüldü. Sıralama hakkında daha fazla bilgiyi şu adreste bulabilirsiniz: belgeleme.
Filtreler ve sorgular
Sürüm 2'den bu yana ES, filtreler ve sorgular arasında ayrım yapmamaktadır. bağlam kavramı tanıtıldı.
Sorgu bağlamı, sorgunun bir _score oluşturması ve önbelleğe alınmaması açısından filtre bağlamından farklıdır. _score'un ne olduğunu size daha sonra göstereceğim.
# получим посты, опубликованные 1ого сентября или позже
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"filter": {
"range": {
"published_at": { "gte": "2014-09-01" }
}
}
}'
Etiketlere göre filtrele
Kullanırız terim sorgusu Belirli bir kelimeyi içeren belge kimliklerini aramak için:
# найдем все документы, в поле tags которых есть элемент 'котята'
curl -XGET "$ES_URL/blog/post/_search?pretty" -d'
{
"_source": [
"title",
"tags"
],
"filter": {
"term": {
"tags": "котята"
}
}
}'
Ancak içerik alanında “hikayeler” ararsak hiçbir şey bulamayız çünkü Dizin yalnızca orijinal kelimeleri içerir, köklerini içermez. Yüksek kaliteli bir arama yapabilmek için analizörü yapılandırmanız gerekir.
Tarla _score gösterileri alaka. İstek bir filtre bağlamında yürütülürse _score değeri her zaman 1'e eşit olacaktır; bu, filtreyle tam bir eşleşme anlamına gelir.
analiz cihazları
analiz cihazları kaynak metni bir dizi simgeye dönüştürmek için gereklidir.
Analizörler bir taneden oluşur Tokenizatör ve birkaç isteğe bağlı Jeton Filtreleri. Tokenizer'ın önünde birkaç tane bulunabilir Karakter Filtreleri. Belirteçler, kaynak dizeyi boşluklar ve noktalama işaretleri gibi belirteçlere böler. TokenFilter belirteçleri değiştirebilir, silebilir veya yenilerini ekleyebilir, örneğin kelimenin yalnızca kökünü bırakabilir, edatları kaldırabilir, eşanlamlıları ekleyebilir. CharFilter - kaynak dizenin tamamını değiştirir, örneğin html etiketlerini keser.
hadi kullanalım api ve standart ve Rus analizcilerin "Kediler hakkında komik hikayeler" dizesini nasıl dönüştürdüklerini görelim:
# используем анализатор standard
# обязательно нужно перекодировать не ASCII символы
curl -XGET "$ES_URL/_analyze?pretty&analyzer=standard&text=%D0%92%D0%B5%D1%81%D0%B5%D0%BB%D1%8B%D0%B5%20%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B8%20%D0%BF%D1%80%D0%BE%20%D0%BA%D0%BE%D1%82%D1%8F%D1%82"
Standart analizör dizeyi boşluklara böldü ve her şeyi küçük harfe dönüştürdü; Rus analizör, önemsiz kelimeleri çıkardı, küçük harfe dönüştürdü ve kelimelerin kökünü bıraktı.
Rus analizcinin hangi Tokenizer, TokenFilters, CharFilters kullandığını görelim:
Html etiketlerini kesecek analizörümüzü Rusçaya dayalı olarak tanımlayalım. Buna varsayılan diyelim, çünkü bu ada sahip bir analizör varsayılan olarak kullanılacaktır.
Öncelikle kaynak dizedeki tüm HTML etiketleri kaldırılacak, ardından tokenizer standardı onu tokenlara bölecek, ortaya çıkan tokenlar küçük harfe geçecek, önemsiz kelimeler kaldırılacak ve kalan tokenlar kelimenin kökü olarak kalacak.
Dizin oluşturma
Yukarıda varsayılan analizörü anlattık. Tüm dize alanlarına uygulanacaktır. Gönderimiz bir dizi etiket içerdiğinden etiketler analizör tarafından da işlenecektir. Çünkü Gönderileri bir etiketle tam eşleşmeye göre arıyoruz, ardından etiketler alanı için analizi devre dışı bırakmamız gerekiyor.
Etiketler alanının analizinin devre dışı bırakıldığı, analizör ve haritalama içeren bir blog2 indeksi oluşturalım:
Aynı 3 gönderiyi bu dizine (blog2) ekleyelim. Bu işlemi atlayacağım çünkü... blog dizinine belge eklemeye benzer.
İfade desteğiyle tam metin araması
Başka bir istek türüne bakalım:
# найдем документы, в которых встречается слово 'истории'
# query -> simple_query_string -> query содержит поисковый запрос
# поле title имеет приоритет 3
# поле tags имеет приоритет 2
# поле content имеет приоритет 1
# приоритет используется при ранжировании результатов
curl -XPOST "$ES_URL/blog2/post/_search?pretty" -d'
{
"query": {
"simple_query_string": {
"query": "истории",
"fields": [
"title^3",
"tags^2",
"content"
]
}
}
}'
Çünkü Rusça kökenli bir analizör kullanıyoruz, bu durumda bu istek, yalnızca 'geçmiş' kelimesini içermesine rağmen tüm belgeleri döndürecektir.
İstek özel karakterler içerebilir, örneğin:
""fried eggs" +(eggplant | potato) -frittata"
Sözdizimi isteği:
+ signifies AND operation
| signifies OR operation
- negates a single token
" wraps a number of tokens to signify a phrase for searching
* at the end of a term signifies a prefix query
( and ) signify precedence
~N after a word signifies edit distance (fuzziness)
~N after a phrase signifies slop amount
# найдем документы без слова 'щенки'
curl -XPOST "$ES_URL/blog2/post/_search?pretty" -d'
{
"query": {
"simple_query_string": {
"query": "-щенки",
"fields": [
"title^3",
"tags^2",
"content"
]
}
}
}'
# получим 2 поста про котиков
Benzer makaleler-derslerle ilgileniyorsanız, yeni makaleler için fikirleriniz varsa veya işbirliği önerileriniz varsa, kişisel mesaj veya e-posta yoluyla bir mesaj almaktan memnuniyet duyarım. [e-posta korumalı].