どのようにドキュメントをルセンインデックス化しますか?


95

Luceneに関するドキュメントを読んだ。また、私はこのリンク(http://lucene.sourceforge.net/talks/pisa)のドキュメントを読みました。

Luceneがドキュメントにインデックスを付ける方法と、Luceneがインデックス付けに使用するアルゴリズムがわかりません。

上記のリンクでは、Luceneがこのアルゴリズムをインデックス作成に使用していると述べています。

  • 増分アルゴリズム:
    • セグメントインデックスのスタックを維持する
    • 着信ドキュメントごとにインデックスを作成する
    • スタックに新しいインデックスをプッシュする
    • b = 10をマージファクターとします。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;
    }
}

このアルゴリズムはどのようにして最適化されたインデックスを提供しますか?

Luceneは、Bツリーアルゴリズムまたはそのような他のアルゴリズムをインデックス作成に使用しますか、または特定のアルゴリズムを持っていますか?


ここではほとんどの回答は、最初のLuceneがいることを正しい作成転置インデックスを、それ用語インデックスがその後取得する方法の重要なポイントを説明していないことを検索(OPが実際にのために尋ね、私は信じている、とあります)。したがって、以下では、この古い質問に対する新しい回答を見つけてください。
fnl 2017

1
現在の回答(私のものを含む!)は、OPの主な2つの質問(Luceneがどのように最適化されたインデックス付けを提供するか、および特定のアルゴリズム(Bツリーではなくスキップリスト)を提供する方法)に答えるには十分ではないため、私の回答をもう一度更新しました。ところで)。私の最終的な更新が実際の質問に正しく答えることを願っています!
fnl 2017

回答:


54

ここにかなり良い記事があります:https : //web.archive.org/web/20130904073403/http : //www.ibm.com/developerworks/library/wa-lucene/

編集12/2014:元のファイルが削除されたため、アーカイブされたバージョンに更新されました。おそらく最も新しい代替策は、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にさらに最新のバージョンがありますが、情報が少ないようです古いものより。

簡単に言えば、luceneがドキュメントにインデックスを付けると、それはいくつかの用語に分解されます。次に、用語をインデックスファイルに保存します。各用語は、その用語を含むドキュメントに関連付けられています。ハッシュテーブルのようなものと考えることができます。

用語は、各単語をそのルート形式にステミングするアナライザーを使用して生成されます。英語で最も一般的なステミングアルゴリズムは、Porterステミングアルゴリズムです。http//tartarus.org/~martin/PorterStemmer/

クエリが発行されると、インデックスの作成に使用されたのと同じアナライザーで処理され、インデックス内の一致する用語を検索するために使用されます。これにより、クエリに一致するドキュメントのリストが提供されます。


回答とリンクをありがとう。しかし、Luceneプロジェクトには「Snowball」という名前の特別なステマーがあると聞きましたか?それについて何か聞いたことがありますか?
M.Amrollahi

これは別の質問です。lucidimagination.com/ search /…を参照してくださいそれ以外は、質問のパターンを確認してください「Lucene in Action」の本を読むことをお勧めします:manning.com/hatcher2(初版は少し日付が古いです枯れ木バージョンに含まれています。第2版は電子書籍として購入できます)。
ユヴァルF

5
答えを変更しても、IBMリンクである最初のリンクが見つからない:)
Adelin

また、フィールドは全体像をどのように入力しますか?クエリが特定のフィールドに対するものである場合、luceneは、どの時点で、ドキュメントを指す用語がドキュメント内のどこにもなく、要求されたフィールド内にあることをどのようにして知っていますか?
Levon Tamrazov、2014年

44

簡単に言うと、Luceneはディスク上のSkip-Lists を使用して逆索引を作成し、次に有限状態トランスデューサー(FST)を使用して索引付き用語のマッピングをメモリーにロードします。ただし、Luceneのインデックスシステムの作者であるMichael McCandlessが説明したように、Lucene はすべてのインデックス付き用語を(必ずしも)RAMにロードしないことに注意してください。スキップリストを使用すると、インデックスを1つのヒットから別のヒットに移動できるため、(Bツリーのように)セットや、特に範囲クエリなどが可能になります。また、スキップリストのインデックス付けに関するWikipediaのエントリでは、Luceneのスキップリストの実装がマルチレベルと呼ばれる理由も説明されています。スキップリスト-基本的に、O(log n)ルックアップを可能にします(これもBツリーのようです)。

したがって、逆スキップ(用語)インデックス(スキップリストデータ構造に基づく)がドキュメントから構築されると、インデックスはディスクに保存されます。次に、Luceneは(すでに述べたように、おそらく一部のみ)これらの用語を、Morfologickに緩やかに触発されたFST実装で、有限状態トランスデューサーロードします。

Michael McCandless(また)は、Luceneが(最小非循環)FST使用してメモリに格納する用語にインデックスSortedMap<ByteSequence,SomeOutput>を付ける方法と理由説明し、基本的にとして、FSTのしくみ(つまり、 FSTがバイトシーケンスを圧縮する方法(つまり、インデックス付きの用語)を使用して、このマッピングのメモリ使用を準線形に拡張します)。また、Luceneが使用する特定のFSTアルゴリズムについても説明しています。

Luceneがスキップリストを使用する理由を知りたい方のために、ほとんどのデータベースは(B +)および/または(B)ツリーを使用していますがこの質問について正しい SOの回答(スキップリストとBツリー)をご覧ください。基本的に、 -その答えはかなり良い、深く説明与えていないあなたは、それによってAと同じ同時パフォーマンスについて増し、Bツリーのすぐ再バランスにないことを決定することができるので、そんなにメイク(インデックスの同時更新「もっと従順に」 Skip-List)ですが、Skip-Listを使用すると、(遅延されているかどうかにかかわらず)バランシング操作を行う必要がありません。 (最終的に)Bツリーに必要(実際、答えが示す/参照するように、Bツリーと[マルチレベル]スキップリストのどちらかが「正しく」実行された場合、パフォーマンスの違いはほとんどありません。)


1
Afaik彼らはBツリーの代わりにスキップリストを使用して、ディスクシークの数を減らしています。スキップリストの一部はメモリに常駐し、インデックスをトラバースするときに必要なディスクIOが非常に少ないためです
Anton

24

質問は、インデックス自体についてではなく、インデックスのマージについてのようです。

低レベルの詳細を無視すれば、インデックス作成プロセスは非常に簡単です。Luceneは、ドキュメントから「逆インデックス」と呼ばれるものを形成します。そのため、テキスト「to be or not to be」とid = 1のドキュメントが入った場合、逆索引は次のようになります。

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

これは基本的にはそれです–単語から与えられた単語を含むドキュメントのリストへのインデックス。このインデックス(単語)の各行は、投稿リストと呼ばれます。その場合、このインデックスは長期保存で永続化されます。

実際にはもちろん物事はもっと複雑です:

  • Luceneは、指定された特定のアナライザーに基づいて一部の単語をスキップする場合があります。
  • 言語のフレキシアを減らすために、ステミングアルゴリズムを使用して単語を前処理できます。
  • 投稿リストには、ドキュメントの識別子だけでなく、ドキュメント内の特定の単語のオフセット(潜在的に複数のインスタンス)やその他の追加情報も含めることができます。

基本的な理解にはそれほど重要ではない、さらに多くの合併症があります。

ただし、Luceneインデックスは追加のみであることを理解することが重要です。ある時点で、アプリケーションはインデックス内のすべての変更をコミット(公開)することを決定します。Luceneはすべてのサービス操作をインデックスで終了し、それを閉じるため、検索に使用できます。コミット後のインデックスは基本的に不変です。このインデックス(またはインデックス部分)はセグメントと呼ばれます。Luceneがクエリの検索を実行すると、使用可能なすべてのセグメントで検索されます。

それで、疑問が生じます– すでにインデックス付けされたドキュメントをどのように変更できます

インデックス付けされたドキュメントの新しいドキュメントまたは新しいバージョンは新しいセグメントでインデックス付けされ、古いバージョンはいわゆるキルリストを使用して以前のセグメントで無効化されます。Killリストは、変更可能なコミット済みインデックスの唯一の部分です。ご想像のとおり、古いインデックスにはほとんど削除されたドキュメントが含まれている可能性があるため、インデックスの効率は時間とともに低下します。

これがマージの出番です。マージは、複数のインデックスを組み合わせて、全体的なインデックスをより効率的にするプロセスです。マージ中に基本的に発生するのは、ライブドキュメントが新しいセグメントにコピーされ、古いセグメントが完全に削除されることです。

この単純なプロセスを使用して、Luceneは検索パフォーマンスの観点からインデックスを適切な状態に維持できます。

お役に立てば幸いです。


1
では、最新の結果を最初に見つけるために、検索は最新のセグメントから開始するのでしょうか。つまり、明確にするために-ドキュメントが更新されたとします。古いバージョンのドキュメントが削除リストに追加され、ドキュメントIDが削除リストのIDと一致する場合、古いセグメントで見つかった一致は検索結果から削除されますか?
ジョエルB

2
はい。それで合っています。言及しなければならないのは、最終的な順序は並べ替え規則(重要な場合の関連性インデックス)を使用して定義されるため、セグメントが検索される順序は関係ないということです。
Denis Bazhenov

12

これは逆インデックスですが、どの構造を使用するかは指定していません。 luceneのインデックス形式には完全な情報があります。
「Summary of File Extensions」から始めます。

最初に、それがさまざまな異なるインデックスについて話していることに気付くでしょう。私が気づく限り、これらは厳密に言えばBツリーを使用していませんが、類似点があります-上記の構造はツリーに似ています。


1
Luceneの逆索引は、Bツリーではなく、スキップリストに基づいています。非常に広い意味ではまだツリーのような構造ですが、完全にするために-たとえば、このSO質問を参照してくださいLuceneのスキップリストの使用このSOの質問は、Bツリーよりもスキップリストの方が望ましい理由です。
fnl 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.