Lucene indeksi nasıl belgelenir?


98

Lucene hakkında bazı belgeler okudum; ayrıca bu bağlantıdaki belgeyi okudum ( http://lucene.sourceforge.net/talks/pisa ).

Lucene'nin belgeleri nasıl indekslediğini gerçekten anlamıyorum ve Lucene'nin indeksleme için hangi algoritmaları kullandığını anlamıyorum?

Yukarıdaki bağlantıda, Lucene'nin bu algoritmayı indeksleme için kullandığını söylüyor:

  • artımlı algoritma:
    • segment endeksleri yığını tutmak
    • her gelen belge için dizin oluştur
    • yığına yeni dizinleri gönder
    • b = 10 birleştirme faktörü olsun; M = 8

for (size = 1; size < M; size *= b) {
    if (there are b indexes with size docs on top of the stack) {
        pop them off the stack;
        merge them into a single index;
        push the merged index onto the stack;
    } else {
        break;
    }
}

Bu algoritma optimize edilmiş indekslemeyi nasıl sağlar?

Lucene, indeksleme için B-ağacı algoritması veya buna benzer başka bir algoritma kullanıyor mu - yoksa belirli bir algoritması var mı?


Buradaki yanıtların çoğu, önce Lucene'nin tersine çevrilmiş indeksi oluşturduğu doğrudur , ancak bu, terim indeksinin daha sonra nasıl arandığının kilit noktasını açıklamıyor (ve inanıyorum ki, OP'nin gerçekte ne istediğini). Öyleyse aşağıda, bu oldukça eski soruya yeni bir cevap bulun ve umarım daha iyi bir fikir verir.
fnl

1
Cevabım bir kez daha güncellendi, çünkü mevcut cevaplar (benimki dahil!) OP'nin ana iki sorusunu cevaplamak için gerçekten tatmin edici değil (Lucene nasıl optimize edilmiş indekslemeyi sağlıyor ve hangi algoritma ile - Atlama Listesi, B-Ağacı değil, BTW). Umarım son güncellemelerim artık asıl soruyu doğru şekilde yanıtlar!
fnl

Yanıtlar:


48

Özetle, Lucene diskte Skip Listelerini kullanarak tersine çevrilmiş bir indeks oluşturur ve ardından Endite State Transducer (FST) kullanarak indekslenmiş terimler için bir eşleme belleğe yükler . Bununla birlikte, Lucene'nin indeksleme sisteminin yazarı Michael McCandless tarafından tarif edildiği gibi, Lucene'nin indekslenmiş tüm terimleri (zorunlu olarak) RAM'e yüklemediğini unutmayın . Atlama Listeleri kullanılarak, dizinin bir isabetten diğerine geçebileceğini ve set ve özellikle aralık sorguları gibi şeyleri (B-Trees'e çok benzer şekilde) mümkün kıldığını unutmayın. Ve atla Listelerini endekslenmesi Wikipedia girişi de lucene en Atla-List uygulaması denir açıklıyor çok seviyeliSkip-List - esasen, O(log n)aramaları mümkün kılmak için (yine, B-Trees gibi).

Dolayısıyla, bir Atlama Listesi veri yapısına dayanan ters (terim) indeks belgelerden oluşturulduğunda, dizin diskte saklanır. Lucene sonra yükler (daha önce belirtildiği gibi: muhtemelen sadece bazı) bir içine bu terimleri Sonlu Devlet Transducer bir FST uygulanmasında, gevşek ilham tarafından Morfologick .

Michael McCandless (ayrıca), Lucene'nin Lucene'nin bellekte sakladığı terimleri indekslemek için nasıl ve neden (minimum döngüsel olmayan) bir FST'yi nasıl ve neden kullandığını açıklamakta oldukça iyi ve kısa bir iş çıkarıyor veSortedMap<ByteSequence,SomeOutput> FST'lerin nasıl çalıştığına dair temel bir fikir veriyor (yani, FST'nin bayt dizilerini nasıl sıkıştırdığı [yani indekslenmiş terimler], bu eşlemenin bellek kullanımının alt doğrusal büyümesini sağlamak için. Lucene'nin de kullandığı FST algoritmasını açıklayan makaleye işaret ediyor .

En veritabanları (B +) kullanırken Lucene, Skip-Listelerini kullanır neden bu meraklı İçin - ve / veya (B) Ağaçları, bakmak doğru SO cevap bu soruya (B-Trees vs atla Listeleri) ile ilgili. Bu cevap oldukça iyi, derin bir açıklama sağlar - esasen, "daha uygun" endeksinin eşzamanlı güncellemelerini çok fazla yapmaz (çünkü bir B-Ağacını hemen yeniden dengelememeye karar verebilirsiniz, böylece bir B-Ağacı ile aynı eşzamanlı performansı elde edebilirsiniz. Listeyi Atla), daha ziyade, Atlama Listeleri sizi (gecikmeli veya gecikmesiz) dengeleme işlemi üzerinde çalışmak zorunda kalmaktan kurtarır. (nihayetinde) B-Trees tarafından ihtiyaç duyulmaktadır (Aslında, yanıtın gösterdiği / referans olduğu gibi, eğer "doğru yapılırsa", B-Trees ve [multi-level] Skip-Listeler arasında muhtemelen çok az performans farkı vardır.)


1
Afaik, disk arama sayısını azaltmak için B-ağacı yerine Atlama Listesini kullanıyorlar, çünkü Atlama Listesinin bir kısmı bellekte bulunuyor ve dizini geçerken çok az disk GÇ gerektiriyor
Anton

56

Burada oldukça iyi bir makale var: https://web.archive.org/web/20130904073403/http://www.ibm.com/developerworks/library/wa-lucene/

Düzenleme 12/2014: Orijinalin silinmesi nedeniyle arşivlenmiş bir sürüme güncellendi, muhtemelen en yeni alternatif http://lucene.apache.org/core/3_6_2/fileformats.html

Http://lucene.apache.org/core/4_10_2/core/org/apache/lucene/codecs/lucene410/package-summary.html#package_description adresinde daha da yeni bir sürüm var , ancak içinde daha az bilgi var gibi görünüyor eskisinden daha.

Özetle, lucene bir belgeyi indekslediğinde, onu birkaç terime ayırır. Daha sonra terimleri, her terimin kendisini içeren belgelerle ilişkilendirildiği bir dizin dosyasında depolar. Bunu bir hashtable gibi düşünebilirsiniz.

Terimler, her kelimeyi kök biçimine alan bir analizci kullanılarak üretilir. İngilizce için en popüler kök belirleme algoritması, Porter kök belirleme algoritmasıdır: http://tartarus.org/~martin/PorterStemmer/

Bir sorgu yayınlandığında, endeksi oluşturmak için kullanılan ve daha sonra dizindeki eşleşen terimleri aramak için kullanılan aynı analizör aracılığıyla işlenir. Bu, sorguyla eşleşen belgelerin bir listesini sağlar.


Cevabınız ve bağlantılarınız için teşekkürler. Ama Lucene projesinin "Kartopu" adında özel bir sabitleyici olduğunu duydum. Bununla ilgili bir şey duydun mu?
Mehdi Amrollahi

Bu farklı bir soru: Bkz. Lucidimagination.com/search/… Bunun dışında, soru kalıbınızı görerek 'Lucene in Action' kitabını okumanızı öneririm: manning.com/hatcher2 (İlk baskı biraz eski olabilir, ancak ölü ağaç versiyonunda bulunur. İkinci baskı bir e-kitap olarak satın alınabilir).
Yuval F

5
Cevabınızı değiştirebilir misiniz, IBM bağlantısı olan ilk bağlantı bulunamadı :)
Adelin

Ayrıca alanlar resmin tamamına nasıl giriyor? Bir sorgu belirli bir alandaysa, lucene belgeye işaret eden terimin belgenin herhangi bir yerinde değil, istenen bir alanın içinde olduğunu nasıl ve hangi noktada biliyor?
Levon Tamrazov

24

Görünüşe göre sorunuz kendi kendini indekslemekten çok indeks birleştirme ile ilgili.

Düşük seviyeli ayrıntıları görmezden gelirseniz indeksleme işlemi oldukça basittir. Lucene, belgelerden "ters çevrilmiş dizin" denen şeyi oluşturur. Dolayısıyla, "Olmak ya da olmamak" metnini içeren belge ve id = 1 gelirse, ters çevrilmiş dizin şöyle görünür:

[to] → 1
[be] → 1
[or] → 1
[not] → 1

Temelde budur - kelimeden verilen kelimeyi içeren belgelerin listesine giden dizin . Bu dizinin (kelime) her satırına kayıt listesi denir. Bu endeks daha sonra uzun süreli depolamada korunur.

Gerçekte elbette işler daha karmaşıktır:

  • Lucene, verilen belirli Analizöre bağlı olarak bazı kelimeleri atlayabilir;
  • sözcükler, dilin esnekliğini azaltmak için kök belirleme algoritması kullanılarak önceden işlenebilir;
  • gönderme listesi yalnızca belgelerin tanımlayıcılarını değil, aynı zamanda belgenin içindeki verilen sözcüğün ofsetini (potansiyel olarak birkaç örnek) ve diğer bazı ek bilgileri de içerebilir.

Temel anlayış için çok önemli olmayan daha birçok komplikasyon var.

Lucene endeksinin yalnızca eklendiğini anlamak önemlidir . Zaman içinde bir noktada uygulama, dizindeki tüm değişiklikleri gerçekleştirmeye (yayınlamaya) karar verir. Lucene, tüm hizmet işlemlerini indeksle bitirir ve kapatır, böylece aranabilir. Kayıt indeksinden sonra temelde değişmez. Bu indeks (veya indeks kısmı) segment olarak adlandırılır . Lucene, bir sorgu için arama yaptığında, mevcut tüm segmentlerde arama yapar.

Öyleyse soru ortaya çıkıyor - zaten indekslenmiş belgeyi nasıl değiştirebiliriz ?

Yeni belgeler veya halihazırda dizine alınmış belgelerin yeni sürümleri, yeni bölümlerde dizine alınır ve eski sürümler, öldürme listesi adı verilen yöntemle önceki bölümlerde geçersiz kılınır . Öldürme listesi, commit edilmiş dizinin değişebilen tek parçasıdır. Tahmin edebileceğiniz gibi, dizin verimliliği zamanla düşer, çünkü eski dizinler çoğunlukla kaldırılmış belgeler içerebilir.

Birleştirme burada devreye giriyor. Birleştirme - genel olarak daha verimli bir dizin oluşturmak için birkaç dizini birleştirme işlemidir. Temelde birleştirme sırasında olan şey, canlı belgelerin yeni bölüme kopyalanması ve eski bölümlerin tamamen kaldırılmasıdır.

Bu basit süreci kullanarak Lucene, dizini arama performansı açısından iyi durumda tutabilir.

Umarım yardımcı olur.


1
Öyleyse, önce en güncel sonuçları bulmak uğruna, en yeni segmentlere bakarak bir arama başlar mı? Yani sadece açıklığa kavuşturmak için - bir belgenin güncellendiğini varsayalım. Belgenin eski sürümü öldürme listesine eklenir ve daha sonra eski bölümlerde bulunan eşleşmeler, belge kimlikleri öldürme listesindeki bir kimlikle eşleşirse arama sonuçlarından kaldırılır mı?
Joel B

2
Evet haklısın. Belirtilmesi gereken tek şey, son sıranın sıralama kuralları kullanılarak tanımlanmasıdır (önemsiz durumda alaka indeksi), bu nedenle segmentlerin aranma sırası alakalı değildir.
Denis Bazhenov

13

Bu edilir endeksi ters , ama bu kullandığı yapı belirtmez. Lucene'deki dizin biçimi tam bilgiye sahiptir.
'Dosya Uzantılarının Özeti' ile başlayın.

İlk önce çeşitli farklı dizinler hakkında konuştuğunu fark edeceksiniz. Farkına vardığım kadarıyla bunların hiçbirinin bir B-ağacını kullanmadığını , ancak benzerlikler var - yukarıdaki yapılar ağaçlara benziyor.


1
Lucene'nin tersine çevrilmiş indeksi, bir B-ağacına değil, bir atlama listesine dayanmaktadır. Yine de çok geniş anlamda ağaç benzeri bir yapı, ancak tam olarak - örneğin, bu GK sorusuna bakın . Lucene'nin bir atlama listesi kullanması ve bu SO sorusu neden atlama listelerinin B-ağaçlarına tercih edilebilir olabileceğidir .
fnl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.