我是Lucene的新手,并且在使字符串字段在一个范围内可搜索时遇到了一些问题。
所以,我有一个由几个字符串字段组成的文档。其中一个是具有表格
的版本1.0,1.1,1.0-RC1 ......即Major.Minor(-RCX)
版本字符串有一个支持java类(Version),它实现了Comparable。
我的分析器是一个分析器包装器,它是一个LowerCase和WhiteSpace分析器,类似于内置的分析器。我使用经典查询解析器进行搜索。搜索确切的术语可以正常工作。
我希望能够做到的是:
查询:“版本:[1.0-RC1至1.5]” - 列出两个值之间的所有文档匹配版本
和
psuedoquery:“someField:value AND version:latest” - 列出所有带有someField = value且具有最新版本的文档
我尝试做的是在索引之前将我的版本字符串转换为int,但是查询输入需要以某种方式进行转换,以便在搜索之前版本字符串变为和int。我还尝试使用具有三维的IntPoint但是来了无处可去。
看起来我必须为版本字段实现自定义分析器,但是我在查找类似示例时遇到了问题。
如果有人能指出我的方向会很棒!
谢谢!
答案 0 :(得分:0)
你没有提到Lucene版本所以我假设最新版(> = 6.0.0)。
TermRangeQuery似乎适合您的需要,但我过去没有使用过这门课程。
我在下面写了示例程序进行测试,它似乎给了我想要的结果。使用以下代码时,请包括所需的lucene罐子。
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;
}
}