そのため、Solrの「docValues」が何であるかを説明しようとする複数のソースを読みましたが、それらをいつ使用する必要があるのか、特にインデックス付きフィールドと格納されたフィールドとの関係がわかりません。誰かがそれにいくつかの光を投げることができますか?
SolrのdocValuesとは何ですか?
Doc値は、Luceneの列ストライドフィールド値のストレージ、または単に非反転インデックスまたは前方インデックスとして説明できます。
Jsonで説明するには:
行指向(格納されたフィールド)
{
'doc1': {'A':1, 'B':2, 'C':3},
'doc2': {'A':2, 'B':3, 'C':4},
'doc3': {'A':4, 'B':3, 'C':2}
}
列指向(docValues)
{
'A': {'doc1':1, 'doc2':2, 'doc3':4},
'B': {'doc1':2, 'doc2':3, 'doc3':3},
'C': {'doc1':3, 'doc2':4, 'doc3':2}
}
DocValuesの目的?
格納されたフィールドは、1つのドキュメントのすべてのフィールド値を行ストライド方式で一緒に格納します。検索では、すべてのフィールド値がドキュメントごとに一度に返されるため、ドキュメントに関連する情報の読み込みが非常に高速になります。
ただし、フィールドをスキャンする必要がある場合(ファセット/ソート/グループ化/強調表示のため)、すべてのドキュメントを反復処理し、反復ごとに各ドキュメントのフィールドをロードする必要があるため、ディスクシークが発生するため、処理が遅くなります。
たとえば、一致するすべてのドキュメントが見つかった場合、並べ替えでは、Luceneはそれぞれのフィールドの値を取得する必要があります。同様に、たとえばファセットエンジンは、ファセットリストを作成するために、結果セットを構成する各ドキュメントに出現する各用語を検索し、ドキュメントIDをプルする必要があります。
現在、この問題には2つの方法で対処できます。
JVMヒープの構造を保持する代わりに、OSのファイルシステムキャッシュを使用してメモリを管理することができます。
いつ使うべきですか?
上記のすべての理由。メモリが少ない環境にいる場合、またはフィールドにインデックスを付ける必要がない場合、DocValuesはファセット/グループ化/フィルタリング/ソート/関数クエリに最適です。また、メモリ要件を増やすことなく、ファセット/グループ/フィルター/ソートできるフィールドの数を増やす可能性もあります。私は生産Solrでdocvalueをソートとファセットに使用しており、これらのクエリのパフォーマンスが大幅に向上しました。
DocValuesの使用例は、@ Persimmoniumによって既に説明されており、かなり明確です。それらは、ファセットやソート、およびIRの世界でのそのような空想的なものに適しています。
docValueとは何か、なぜそこにあるのか? docValueは、ドキュメントが値を指すように前方インデックスを構築する方法にすぎません。これらは、インデックス時に構築されたドキュメントから値へのマッピングを提供することによってFieldCacheの制限を克服するために構築され、列ベースの方法で値を格納し、ドキュメントのインデックス付け中にすべての負荷の大きい処理を行います。
docvaluesとは:
NRT互換:インデックス時に構築されるセグメントごとのデータ構造であり、データが急速に変化するユースケースで効率的になるように設計されています。
基本的なクエリ/フィルターのサポート: docvaluesフィールドに対して、インデックスを作成しなくても基本的な用語、範囲などのクエリを実行できますが、これらは定数スコアのみであり、通常は低速です。パフォーマンスとスコアリングに関心がある場合は、フィールドにもインデックスを付けます。
fieldcacheよりも圧縮率が高い: Docvaluesフィールドはfieldcacheよりも圧縮率が高く、「狂気」は不可能です。
ヒープメモリ外にデータを保存できます: fieldType(docValuesFormat = "Disk")に別のdocValuesFormatを指定して、ヒープに最小限のデータのみをロードし、他のデータ構造をディスクに保持できます。
docvaluesでないもの:
保存されたフィールドの代替ではありません:これらはあらゆる方法で保存されたフィールドとは関係なく、代わりに検索用のデータ構造(ソート/ファセット)です/ group/join/scoring)。
このようにLucene docValuesで使用するユースケース。
public Bits getDocsWithField(FieldInfo field) throws IOException {
switch(field.getDocValuesType()) {
case SORTED_SET:
return DocValues.docsWithValue(getSortedSet(field), maxDoc);
case SORTED_NUMERIC:
return DocValues.docsWithValue(getSortedNumeric(field), maxDoc);
case SORTED:
return DocValues.docsWithValue(getSorted(field), maxDoc);
case BINARY:
BinaryEntry be = binaries.get(field.number);
return getMissingBits(be.missingOffset);
case NUMERIC:
NumericEntry ne = numerics.get(field.number);
return getMissingBits(ne.missingOffset);
default:
throw new AssertionError();
}
}
それらが格納され、アクセスされる方法により、ソート、ファセットなどの一部の操作が高速化されます。
その上、それらはいくつかの機能を使用するために必須です:ストリーミング式、インプレース更新...
したがって、疑問がある場合: