2013-07-03 83 views
0

我有一個緩存的名稱列表,我將其存儲到Lucene數據結構中。我想獲得名字以特定字母開頭的人。如何獲得以Lucene中的特定字母開頭的記錄

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

foo bar 
blabla foo 
foo2 bar 
test data 

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

有什麼想法?

+0

你可以看到我的帖子更新,並運行示例? – jrey

回答

1

通配符搜索

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")); 

     } 
+2

我已經知道了。我想搜索首字母爲A的句子,例如'A'。它應該找到「Alice Run」而不是「Run Alice」。 – ftb

+0

你可以設置使用正則表達式,例如regexQueryNrHits(「^ a。* $」,newJavaUtilRegexCapabilies()) – jrey

+1

您是否指的是[這個問題](http://stackoverflow.com/questions/7052492/find-regular-表達式匹配使用-lucene的)? 'regexQueryNrHits'幾乎不是標準的lucene庫的東西......據我所知,無論如何,Lucene RegexpQuery不支持'^'和'$'或任何其他樣式的開始/結束行語法。 – femtoRgon

0

這就是Lucene默認的oeprates。如果將字段標記爲術語,並且搜索字段中任何地方出現的術語。對於大型文本文檔,這是絕對有意義的,因爲您可能從不想從大量文本開始搜索。

如果你想能夠搜索的文本字符串,而不是一個符號化組術語,最好的解決辦法是索引它在支持好辦法。 A Solr.StrField是此類型的典型選擇,而不是TextField

1

建議在沒有標記的情況下使用該字段。
此外,而不是使用通配符搜索中使用將產生的令牌,並會快得多那麼通配符搜索,因爲它會在索引時間發生的EdgeNGramTokenFilter

相關問題