2017-09-25 62 views
1

我是Lucene的新成員,並且在使字符串字段在某個範圍內可搜索時遇到一些問題。使lucene字符串字段範圍可搜索

所以,我有一個由幾個字符串字段組成的文檔。其中之一是CA具有形式

1.0,1.1,1.0-RC1 ...即MAJOR.MINOR(-rcx)

版本串具有一個背襯java類(版本),它實現一個版本可比。

我的分析器是一個分析器包裝器,它是一個LowerCase和WhiteSpace分析器,類似於內置分析器。我使用經典查詢解析器進行搜索。準確的術語搜索工作正常。

查詢:

我希望能夠做到這一點「版本:1.0-RC1到1.5]」 - 列表中的所有文件匹配之間的版本和包括兩個值

psuedoquery:「someField:價值和版本:最新的」 - 列出具有最新版本

someField =值我試圖做的是我的版本字符串轉換爲索引前一個int的所有文件,但查詢輸入需要轉換不知怎的,所以版本字符串變得和int在搜索之前。我也用三維實驗IntPoint,但沒有與它一起。

它看起來像我必須實現版本字段的自定義分析器,但我有問題找到類似的例子。

如果任何人都可以指出我會朝着正確的方向發展,那就太棒了!

謝謝!

回答

0

你還沒有提到Lucene版本,所以我假設最新(> = 6.0.0)。

TermRangeQuery似乎適合您的需要,但我以前沒有使用過這門課。

我寫了下面的示例程序來測試,它似乎給我想要的結果。請在使用下面的代碼時包含所需的lucene jar。

package lucene.productversion; 

import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.core.SimpleAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field.Store; 
import org.apache.lucene.document.StringField; 
import org.apache.lucene.index.DirectoryReader; 
import org.apache.lucene.index.IndexReader; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.index.IndexWriterConfig; 
import org.apache.lucene.index.IndexWriterConfig.OpenMode; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.ScoreDoc; 
import org.apache.lucene.search.TermRangeQuery; 
import org.apache.lucene.search.TopDocs; 
import org.apache.lucene.store.FSDirectory; 


public class App 
{ 
    private static String versionField = "version"; 

    public static void main(String[] args) throws IOException 
    { 
     App app = new App(); 

     System.out.println("Staring Product Version!"); 

     File indexDir = new File("D:\\experiments"); 
     FSDirectory directory = FSDirectory.open(indexDir.toPath()); 

     Analyzer analyzer = new SimpleAnalyzer(); 

     app.index(analyzer, directory); 

     app.search(analyzer, directory); 

     System.out.println("End Product Version!"); 

    } 

    private void search(Analyzer analyzer,FSDirectory directory) throws IOException{ 

     IndexReader reader = DirectoryReader.open(directory); 
     IndexSearcher searcher = new IndexSearcher(reader); 

     Query query = TermRangeQuery.newStringRange(versionField, "1.0", "2.1-RC2", true, true); 

     TopDocs topDocs = searcher.search(query, 10); 


     if(topDocs.totalHits <= 0){ 
      System.out.println("No Hits Found"); 
      return; 
     } 

     for(ScoreDoc doc:topDocs.scoreDocs){ 
      System.out.println("Doc Id :"+doc.doc+" Version Number :"+searcher.doc(doc.doc).get(versionField)); 
     } 

     reader.close(); 

     System.out.println("Searching Completed"); 
    } 

    private void index(Analyzer analyzer,FSDirectory directory) throws IOException{ 

     IndexWriterConfig config = new IndexWriterConfig(analyzer); 

     config.setOpenMode(OpenMode.CREATE); 

     IndexWriter writer = new IndexWriter(directory, config); 


     for(String version:versions()){ 
      Document doc = new Document(); 

      doc.add(new StringField(versionField,version,Store.YES)); 

      writer.addDocument(doc); 

     } 

     writer.commit(); 
     writer.close(); 

     System.out.println("Indexing Completed"); 
    } 

    private List<String> versions(){ 

     List<String> versions = new ArrayList<>(); 

     versions.add("1.0"); 
     versions.add("1.0-RC1"); 
     versions.add("1.1"); 
     versions.add("1.2"); 
     versions.add("2.1-RC1"); 
     versions.add("2.1-RC2"); 
     versions.add("2.1-RC3"); 
     versions.add("3.1-RC1"); 
     versions.add("3.1"); 

     return versions; 
    } 
}