2010-07-14 41 views
11

Tôi muốn kết hợp truy vấn phạm vi số với truy vấn cụm từ trong Lucene. Ví dụ, tôi muốn tìm kiếm các tài liệu mà tôi đã lập chỉ mục có chứa từ 10 đến 20 trang và có tiêu đề "Hello World".Kết hợp Truy vấn Phạm vi Số với Truy vấn Thời hạn trong Lucene

Dường như dường như không thể sử dụng QueryParser để tạo truy vấn này cho tôi; truy vấn phạm vi mà QueryParser tạo ra dường như là văn bản.

Tôi chắc chắn sẽ đánh giá cao ví dụ về cách kết hợp truy vấn phạm vi số với truy vấn cụm từ. Tôi cũng sẽ mở một cách khác để tìm kiếm chỉ mục của mình.

Cảm ơn

Trả lời

10

Có vẻ như tôi đã tự mình tìm ra điều này. Bạn có thể sử dụng truy vấn Query.combine() tới OR cùng nhau. Tôi đã bao gồm một ví dụ dưới đây.

String termQueryString = "title:\"hello world\""; 
Query termQuery = parser.parse(termQueryString); 

Query pageQueryRange = NumericRangeQuery.newIntRange("page_count", 10, 20, true, true); 

Query query = termQuery.combine(new Query[]{termQuery, pageQueryRange}); 
+0

Bạn có biết làm thế nào để thực hiện nó trên Lucene4? Có vẻ như, Query.combine() không hoạt động trong Lucene4 – Dewsworld

+1

Hey @Dewsworld, giải pháp là sử dụng Truy vấn Boolean: Truy vấn BooleanQuery = new BooleanQuery(); truy vấn.Thêm (new TermQuery (...), BooleanClause.Occur.MUST); truy vấn.Thêm (new Term.Query (...), BooleanClause.Occur.KHÔNG BAO GIỜ); –

0
RangeQuery amountQuery = new RangeQuery(lowerTerm, upperTerm, true); 

xử lý Lucene số như lời, vì vậy những con số được sắp xếp theo thứ tự abc.

1 
12 
123 
1234 
etc. 

Điều đó đang được nói, bạn vẫn có thể sử dụng truy vấn phạm vi, bạn chỉ cần thông minh hơn về nó.

Để truy vấn giá trị số một cách chính xác, bạn cần phải pad số nguyên của bạn để độ dài tương tự (bất kể giá trị tối đa của bạn được hỗ trợ là)

0001 
0012 

1234 

Rõ ràng, điều này không làm việc cho số âm (từ - 2 < -1), và hy vọng bạn sẽ không phải đối phó với chúng. Dưới đây là một bài viết hữu ích cho các từ khóa phủ định nếu bạn gặp phải chúng: http://wiki.apache.org/lucene-java/SearchNumericalFields

5

Bạn cũng có thể tạo ra một QueryParser tùy chỉnh trọng protected Query getRangeQuery(...) phương pháp, mà nên trở NumericRangeQuery dụ khi "page_count" lĩnh vực đang gặp phải.

Giống như rất ...

public class CustomQueryParser extends QueryParser { 

    public CustomQueryParser(Version matchVersion, String f, Analyzer a) { 
     super(matchVersion, f, a); 
    } 

    @Override 
    protected Query getRangeQuery(final String field, final String part1, final String part2, final boolean inclusive) throws ParseException { 

     if ("page_count".equals(field)) { 
      return NumericRangeQuery.newIntRange(field, Integer.parseInt(part1), Integer.parseInt(part2), inclusive, inclusive); 
     } 

     // return default 
     return super.getRangeQuery(field, part1, part2, inclusive);  
    } 
} 

Sau đó sử dụng CustomQueryParser khi phân tích cú pháp truy vấn văn bản ..

Giống như rất ...

... 
final QueryParser parser = new CustomQueryParser(Version.LUCENE_35, "some_default_field", new StandardAnalyzer(Version.LUCENE_35)); 
final Query q = parser.parse("title:\"hello world\" AND page_count:[10 TO 20]"); 
... 

này tất cả, tất nhiên, giả sử rằng NumericField(...).setIntValue(...) được sử dụng khi page_count giá trị được thêm vào tài liệu

+0

Điều này cũng được đề xuất trong Lucene Api Javadoc. Cảm ơn –

2

Bạn có thể sử dụng BooleanQuery:

var combinedQuery = new BooleanQuery(); 
combinedQuery.Add(new TermQuery(new Term("title","hello world")),Occur.MUST); 
combinedQuery.Add(NumericRangeQuery.newIntRange("page_count", 10, 20, true, true),Occur.MUST); 
Các vấn đề liên quan