1

私は Lucene 4.1 を使用して、キーワードと値のペアのインデックスを作成しています。キーワードと値は実際の単語ではありません。つまり、電圧、設定であり、分析またはトークン化する必要はありません。例: $P14R / 16777216. (これは、フロー サイトメトリストの FCS データです)

インデックス付けのために、indexed = true、stored = true、tokenized = falseで FieldType を作成します。これらは、私が本を持っている Lucene 1 の古代の Field.Keyword を模倣しています。:-) fieldType もフリーズします。

これらの値がデバッガーに表示されます。ドキュメントとインデックスを作成します。

インデックスとドキュメントを読み、デバッガーでフィールドを見ると、すべてのフィールドが表示されます。名前とフィールドデータは正しいようです。ただし、FieldType が間違っています。indexed = true、stored = true、tokenized = trueを示しています。その結果、(TermQuery を使用した) 検索が機能しません。

どうすればこれを修正できますか? ありがとう。

ps IndexWriterConfig で KeywordAnalyzer を使用しています。後でデモ コードを投稿しようと思いますが、今日は私の本業です。:-)

デモコード:

public class LuceneDemo {

  public static void main(String[] args) throws IOException {
    Directory lDir = new RAMDirectory();
    Analyzer analyzer = new KeywordAnalyzer();
    IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_41, analyzer);
    iwc.setOpenMode(OpenMode.CREATE);
    IndexWriter writer = new IndexWriter(lDir, iwc);

    // BTW, Lucene, anyway you could make this even more tedious???
    // ever heard of builders, Enums, or even old fashioned bits?
    FieldType keywordFieldType = new FieldType();
    keywordFieldType.setStored(true);
    keywordFieldType.setIndexed(true);
    keywordFieldType.setTokenized(false);

    Document doc = new Document();
    doc.add(new Field("$foo",  "$bar123", keywordFieldType));
    doc.add(new Field("contents",  "$foo=$bar123", keywordFieldType));
    doc.add(new Field("$foo2",  "$bar12345", keywordFieldType));

    Field onCreation = new Field("contents",  "$foo2=$bar12345", keywordFieldType);
    doc.add(onCreation);
    System.out.println("When creating, the field's tokenized is " + onCreation.fieldType().tokenized());
    writer.addDocument(doc);
    writer.close();

    IndexReader reader = DirectoryReader.open(lDir);
    Document d1 = reader.document(0);
    Field readBackField = (Field) d1.getFields().get(0);
    System.out.println("When read back the field's tokenized is " + readBackField.fieldType().tokenized());

    IndexSearcher searcher = new IndexSearcher(reader);

// exact match works
Term term = new Term("$foo", "$bar123" );
    Query query = new TermQuery(term);
    TopDocs results = searcher.search(query, 10);
    System.out.println("when searching for : " + query.toString() + "  hits = " + results.totalHits);

    // partial match fails
    term = new Term("$foo", "123" );
    query = new TermQuery(term);
    results = searcher.search(query, 10);
    System.out.println("when searching for : " + query.toString() + "  hits = " + results.totalHits);

    // wildcard search works
    term = new Term("contents", "*$bar12345" );
    query = new WildcardQuery(term);
    results = searcher.search(query, 10);
    System.out.println("when searching for : " + query.toString() + "  hits = " + results.totalHits);
    }
}

出力は次のようになります。

When creating, the field's tokenized is false
When read back the field's tokenized is true
when searching for : $foo:$bar123  hits = 1
when searching for : $foo:123  hits = 0
when searching for : contents:*$bar12345  hits = 1
4

3 に答える 3

1

トークン化したくないフィールドにKeywordAnalyzerを使用することができます。

複数のアナライザーが必要な場合 (つまり、トークン化が必要な他のフィールドがある場合)、PerFieldAnalyzerWrapperがその方法です。

于 2013-03-01T16:35:36.553 に答える
0

デモコードは、トークン化された値が読み戻されたときに異なることを証明しています。それがバグかどうかわからない。

しかし、それが部分検索が機能しない理由ではありません。部分検索が機能しないため、Luceneは部分検索を実行しません(ワイルドカードを使用しない場合)。たとえば、StackOverflowで次のように言います。

ずっとグーグルを使っていたので、理解できなかったと思います。:-)

于 2013-03-02T07:25:58.343 に答える