3

次の形式でドキュメントに追加する UUID フィールドがあります: 372d325c-e01b-432f-98bd-bc4c949f15b8。ただし、UUID でドキュメントをクエリしようとすると、どのように式をエスケープしようとしても返されません。例えば:

+uuid:372d325c-e01b-432f-98bd-bc4c949f15b8
+uuid:"372d325c-e01b-432f-98bd-bc4c949f15b8"
+uuid:372d325c\-e01b\-432f\-98bd\-bc4c949f15b8
+uuid:(372d325c-e01b-432f-98bd-bc4c949f15b8)
+uuid:("372d325c-e01b-432f-98bd-bc4c949f15b8")

そして、次のように TermQuery を使用して QueryParser を完全にスキップすることさえできます:

new TermQuery(new Term("uuid", uuid.toString()))

または

new TermQuery(new Term("uuid", QueryParser.escape(uuid.toString())))

これらの検索ではドキュメントは返されませんが、UUID の一部を検索するとドキュメントが返されます。たとえば、これらは何かを返します:

+uuid:372d325c
+uuid:e01b
+uuid:432f

これらの文書を UUID で引き出せるように、これらの文書に索引を付けるにはどうすればよいですか? ハイフンを削除するために UUID を再フォーマットすることを検討しましたが、まだ実装していません。

4

3 に答える 3

3

これを機能させる唯一の方法は、StandardAnalyzer の代わりに WhitespaceAnalyzer を使用することです。次に、次のように TermQuery を使用します。

IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, new WhitespaceAnalyzer(Version.LUCENE_36))
            .setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
writer = new IndexWriter( directory, config);

次に検索します。

TopDocs docs = searcher.search(new TermQuery(new Term("uuid", uuid.toString())), 1);

WhitespaceAnalyzer は、Lucene が UUID をハイフンで分割するのを防ぎました。別のオプションとして、UUID からダッシュを削除することもできますが、Wh​​itespaceAnalyzer を使用しても私の目的には十分に機能します。

于 2012-10-19T04:45:01.073 に答える
0

UUID フィールドをルックアップ キーとして使用する場合は、トークン化を行わずにフィールド全体を単一の文字列としてインデックス化するように Lucene に依頼する必要があります。これは、UUID フィールドに適切な FieldType を設定することによって行われます。Lucene 4 以降では、StringField を使用できます。

import java.io.IOException;
import java.util.UUID;
import junit.framework.Assert;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

/**
 * Using Lucene 4.7 on Java 7.
 */
public class LuceneUUIDFieldLookupTest {

    private Directory directory;
    private Analyzer analyzer;

    @Test
    public void testUsingUUIDAsLookupKey() throws IOException, ParseException {

        directory = new RAMDirectory();
        analyzer = new StandardAnalyzer(Version.LUCENE_47);

        UUID docUUID = UUID.randomUUID();
        String docContentText1 = "Stack Overflow is a question and answer site for professional and enthusiast programmers.";

        index(docUUID, docContentText1);

        QueryParser parser = new QueryParser(Version.LUCENE_47, MyIndexedFields.DOC_TEXT_FIELD.name(), analyzer);
        Query queryForProgrammer = parser.parse("programmers");

        IndexSearcher indexSearcher = getIndexSearcher();
        TopDocs hits = indexSearcher.search(queryForProgrammer, Integer.MAX_VALUE);
        Assert.assertTrue(hits.scoreDocs.length == 1);

        Integer internalDocId1 = hits.scoreDocs[0].doc;
        Document docRetrieved1 = indexSearcher.doc(internalDocId1);
        indexSearcher.getIndexReader().close();

        String docText1 = docRetrieved1.get(MyIndexedFields.DOC_TEXT_FIELD.name());
        Assert.assertEquals(docText1, docContentText1);

        String docContentText2 = "TechCrunch is a leading technology media property, dedicated to ... according to a new report from the Wall Street Journal confirmed by Google to TechCrunch.";
        reindex(docUUID, docContentText2);

        Query queryForTechCrunch = parser.parse("technology");
        indexSearcher = getIndexSearcher(); //you must reopen directory because the previous IndexSearcher only sees a snapshoted directory.
        hits = indexSearcher.search(queryForTechCrunch, Integer.MAX_VALUE);
        Assert.assertTrue(hits.scoreDocs.length == 1);

        Integer internalDocId2 = hits.scoreDocs[0].doc;
        Document docRetrieved2 = indexSearcher.doc(internalDocId2);
        indexSearcher.getIndexReader().close();

        String docText2 = docRetrieved2.get(MyIndexedFields.DOC_TEXT_FIELD.name());
        Assert.assertEquals(docText2, docContentText2);
    }

    private void reindex(UUID myUUID, String docContentText) throws IOException {
        try (IndexWriter indexWriter = new IndexWriter(directory, getIndexWriterConfig())) {
            Term term = new Term(MyIndexedFields.MY_UUID_FIELD.name(), myUUID.toString());
            indexWriter.updateDocument(term, buildDoc(myUUID, docContentText));
        }//auto-close
    }

    private void index(UUID myUUID, String docContentText) throws IOException {
        try (IndexWriter indexWriter = new IndexWriter(directory, getIndexWriterConfig())) {
            indexWriter.addDocument(buildDoc(myUUID, docContentText));
        }//auto-close
    }

    private IndexWriterConfig getIndexWriterConfig() {
        return new IndexWriterConfig(Version.LUCENE_47, analyzer).setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
    }

    private Document buildDoc(UUID myUUID, String docContentText) {
        Document doc = new Document();
        doc.add(new Field(
                MyIndexedFields.MY_UUID_FIELD.name(),
                myUUID.toString(),
                StringField.TYPE_STORED));//use TYPE_STORED if you want to read it back in search result.

        doc.add(new Field(
                MyIndexedFields.DOC_TEXT_FIELD.name(),
                docContentText,
                TextField.TYPE_STORED));

        return doc;
    }

    private IndexSearcher getIndexSearcher() throws IOException {
        DirectoryReader ireader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(ireader);
        return indexSearcher;
    }

    enum MyIndexedFields {

        MY_UUID_FIELD,
        DOC_TEXT_FIELD
    }
}
于 2014-03-25T00:58:46.403 に答える
0

Lucene Query Syntax rulesによると、クエリは

+uuid:372d325c\-e01b\-432f\-98bd\-bc4c949f15b8

動作するはずです。

そうでないuuid場合は、ドキュメントがインデックスに挿入されたときに、フィールドにデータが入力されていないためだと思います。このフィールドに正確に何が挿入されているか確認できますか? Lukeを使用してインデックスをクロールし、フィールドに格納されている実際の値を探すことができますuuid

于 2012-10-05T22:23:48.053 に答える