【问题标题】:Make lucene string field range searchable使 lucene 字符串字段范围可搜索
【发布时间】:2017-09-25 07:44:40
【问题描述】:

我是 Lucene 新手,在使字符串字段可在某个范围内搜索时遇到了一些问题。

所以,我有一个包含几个字符串字段的文档。其中之一是具有以下形式的版本

1.0, 1.1, 1.0-RC1...即Major.Minor(-RCX)

版本字符串有一个实现 Comparable 的支持 Java 类 (Version)。

我的分析器是一个分析器包装器,它是一个小写和空白分析器,类似于内置分析器。我使用经典查询解析器进行搜索。按确切字词搜索效果很好。

我想做的是这样的:

query: "version:[1.0-RC1 TO 1.5]" - 列出两个值之间(包括两个值)的所有文档匹配版本

psuedoquery: "someField:value AND version:latest" - 列出 someField = value 具有最新版本的所有文档

我尝试做的是在索引之前将我的版本字符串转换为int,但是查询输入需要以某种方式转换,以便在搜索之前版本字符串变为和int。我也尝试了具有三个维度的IntPoint但是来了无处可去。

看起来我必须为版本字段实现一个自定义分析器,但我在查找类似示例时遇到了问题。

如果有人能指出我正确的方向,那就太好了!

谢谢!

【问题讨论】:

    标签: java lucene


    【解决方案1】:

    您没有提到 Lucene 版本,所以我假设是最新版本( >= 6.0.0 )。

    TermRangeQuery 似乎适合您的需要,但我过去没有使用过这个类。

    我已经编写了下面的示例程序进行测试,它似乎给了我想要的结果。使用以下代码时,请包括所需的 lucene jars。

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-20
      • 2017-01-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      • 2017-07-17
      相关资源
      最近更新 更多