【问题标题】:Lucene LongPoint Range search doesn't workLucene LongPoint Range 搜索不起作用
【发布时间】:2022-04-07 01:59:26
【问题描述】:

我在 Java 11 中使用 Lucene 8.2.0。

我正在尝试索引 Long 值,以便我可以使用范围查询对其进行过滤,例如:+my_range_field:[1 TO 200]。然而,它的任何变体,即使是my_range_field:[* TO *],返回0 都会导致这个最小示例。一旦我从中删除+ 使其成为OR,我就会得到2 结果。

所以我想我在索引它的方式上一定犯了一个错误,但我无法弄清楚它可能是什么。

来自LongPointJavaDoc

用于快速范围过滤器的索引长字段。如果您还需要存储该值,则应添加一个单独的 StoredField 实例。 在搜索时查找 N 维形状或范围内的所有文档是有效的。一个文档中的同一字段允许多个值。

这是我的最小示例:

public static void main(String[] args) {
    Directory index = new RAMDirectory();
    StandardAnalyzer analyzer = new StandardAnalyzer();

    try {
        IndexWriter indexWriter = new IndexWriter(index, new IndexWriterConfig(analyzer));

        Document document1= new Document();
        Document document2= new Document();

        document1.add(new LongPoint("my_range_field", 10));
        document1.add(new StoredField("my_range_field", 10));
        document2.add(new LongPoint("my_range_field", 100));
        document2.add(new StoredField("my_range_field", 100));

        document1.add(new TextField("my_text_field", "test content 1", Field.Store.YES));
        document2.add(new TextField("my_text_field", "test content 2", Field.Store.YES));

        indexWriter.deleteAll();
        indexWriter.commit();
        indexWriter.addDocument(document1);
        indexWriter.addDocument(document2);
        indexWriter.commit();
        indexWriter.close();

        QueryParser parser = new QueryParser("text", analyzer);
        IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(index));

        String luceneQuery = "+my_text_field:test* +my_range_field:[1 TO 200]";
        Query query = parser.parse(luceneQuery);

        System.out.println(indexSearcher.search(query, 10).totalHits.value);
    } catch (IOException e) {

    } catch (ParseException e) {

    }
}

【问题讨论】:

    标签: java indexing lucene java-11 range-query


    【解决方案1】:

    您需要首先使用 StandardQueryParser,然后为解析器提供 PointsConfig 映射,实质上暗示哪些字段将被视为 Points。您现在将获得 2 个结果。

    // Change this line to the following
    StandardQueryParser parser = new StandardQueryParser(analyzer);
    IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(dir));
    
    /* Added code */
    PointsConfig longConfig = new PointsConfig(new DecimalFormat(), Long.class);
    Map<String, PointsConfig> pointsConfigMap = new HashMap<>();
    pointsConfigMap.put("my_range_field", longConfig);
    parser.setPointsConfigMap(pointsConfigMap);
    /* End of added code */
    
    String luceneQuery = "+my_text_field:test* +my_range_field:[1 TO 200]";
    // Change the query to the following
    Query query = parser.parse(luceneQuery, "text");
    

    【讨论】:

    • 请接受这个作为答案。当前接受的答案表明查询解析器无法解析您尝试的字符串。这个答案向您展示了如何设置它以正确解析您的字符串。
    【解决方案2】:

    我找到了解决问题的方法。

    我的印象是查询解析器可以正确解析任何查询字符串。好像不是这样的。

    使用

    Query rangeQuery = LongPoint.newRangeQuery("my_range_field", 1L, 11L);
    Query searchQuery = new WildcardQuery(new Term("my_text_field", "test*"));
    Query build = new BooleanQuery.Builder()
        .add(searchQuery, BooleanClause.Occur.MUST)
        .add(rangeQuery, BooleanClause.Occur.MUST)
        .build();
    
    

    返回正确的结果。

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      相关资源
      最近更新 更多