簡體   English   中英

如何從Lucene的特定字母開始獲取記錄

[英]How to get records starting with a specific letter in Lucene

我有一個緩存的名稱列表,我存儲到Lucene數據結構。 我希望得到名字以特定字母開頭的人。

例如:我的列表如下。 我將它們存儲在name字段中。

foo bar
blabla foo
foo2 bar
test data

當我用name:f*搜索name:f*它返回foo barfoo2 barblabla foo 它會檢查字段中的每個單詞並獲得blabla foo 但是我需要以f開頭的名字,它的第一個字母是f ,而不是記錄包含以f開頭的單詞,即使它們在句子的末尾。

任何想法 ?

通配符搜索

Lucene支持單個術語內的單個和多個字符通配符搜索(不在短語查詢中)。

要執行單個字符通配符搜索,請使用“?” 符號。

要執行多字符通配符搜索,請使用“*”符號。

單字符通配符搜索查找與替換的單個字符匹配的術語。 例如,要搜索“文本”或“測試”,您可以使用搜索:

te?t多字符通配符搜索查找0個或更多字符。 例如,要搜索測試,測試或測試人員,您可以使用搜索:

測試*

例如,使用正則表達式

RegexQuery query = new RegexQuery(newTerm("^a.*$"));


query.setRegexImplementation(new JavaUtilRegexCapabilities());

return searcher.search(query, null, 1000).totalHits;

http://lucene.apache.org/core/4_3_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description

示例代碼:

        BasicConfigurator.configure();

        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);

        // Store the index in memory:
        Directory directory = new RAMDirectory();
        // To store an index on disk, use this instead:
        // Directory directory = FSDirectory.open(new
        // File("./lucene/data"));
        IndexWriterConfig config = new IndexWriterConfig(
                Version.LUCENE_CURRENT, analyzer);
        IndexWriter iwriter;

        iwriter = new IndexWriter(directory, config);

        String[] words = { "Olimpia", "Cerro", "Olimpo", "Libertad",
                "Nacional", "Sol", "O'higgins", "Sao Paulo",
                "Oriente Petrolero", "Barrio Obrero", "B. Obrero" };

        for (String word : words) {
            Document doc = new Document();
            String text = word;
            doc.add(new Field("name", text, Field.Store.YES,
                    Field.Index.NOT_ANALYZED));

            // ,Field.Store.NO, Field.Index.NOT_ANALYZED
            iwriter.addDocument(doc);
        }

        iwriter.close();

        // Now search the index:

        logger.info("HelloLucene.main: query2 -----------");

        DirectoryReader ireader2 = DirectoryReader.open(directory);
        IndexSearcher isearcher2 = new IndexSearcher(ireader2);

        logger.info("HelloLucene.main: query2 -----------");
        RegexQuery query2 = new RegexQuery(new Term("name", "O.*"));
        query2.setRegexImplementation(new JavaUtilRegexCapabilities(
                JavaUtilRegexCapabilities.FLAG_CASE_INSENSITIVE));

        ScoreDoc[] hits2 = isearcher2.search(query2, null, 1000).scoreDocs;
        for (int i = 0; i < hits2.length; i++) {
            Document hitDoc = isearcher2.doc(hits2[i].doc);
            logger.info("HelloLucene.main: starting with O = "
                    + hitDoc.get("name"));

        }

建議使用沒有標記化的字段。
此外,不使用通配符搜索,而是使用EdgeNGramTokenFilter來生成令牌,並且比通配符搜索要快得多,因為它會在索引時發生。

默認情況下,Lucene就是這樣做的。 如果將字段標記為術語,則搜索字段中任何位置的術語。 對於大型文本文檔,這是絕對有意義的,因為您可能永遠不會只想從大量文本的開頭搜索。

如果您希望能夠搜索文字字符串而不是標記化的術語集,那么最佳解決方案是以支持該字符串的方式對其進行索引。 Solr.StrField是典型的類型選擇,而不是TextField

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM