2010-01-13 26 views
8

Làm cách nào để thực hiện "OR" trong Lucene.NET. Về cơ bản những gì tôi có là một mảng các ID và tôi muốn trả về bất kỳ bản ghi nào trong đó một trường cụ thể chứa bất kỳ giá trị nào. Trước đây tôi đã làm điều này chỉ với một giá trị, nhưng bây giờ tôi muốn chuyển đổi mã sau để MetaDataID là một mảng các giá trị có thể thay vì một giá trị duy nhất.Lucene.NET "HOẶC"

if (MetaDataID.Length > 0) 
    completeQuery.Add(new QueryParser("MetaData", new StandardAnalyzer()).Parse(MetaDataID), BooleanClause.Occur.MUST); 

Trả lời

4

Bạn cần phải sử dụng BooleanClause.Occur.SHOULD thay vì BooleanClause.Occur.MUST

ví dụ .:

BooleanQuery booleanQuery = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
booleanQuery.add(query1, BooleanClause.Occur.SHOULD); 
booleanQuery.add(query2, BooleanClause.Occur.SHOULD); 
+0

điều này dường như không trả lại tập hợp A | B. Khi tôi thử điều này, tôi nhận được tất cả các bản ghi khớp với mệnh đề MUST khác. Đó là để nói rằng nó xuất hiện như thể các NÊN đang bị bỏ qua. – Kyle

+1

Không hoàn toàn chắc chắn tôi hiểu bạn. Nhưng tôi nghĩ rằng những gì bạn cần phải làm tổ BooleanQueries của bạn. –

+0

'Bạn cần sử dụng blah ...' - nhưng tại sao? –

2

Hãy cẩn thận khi sử dụng BooleanQuery để lấy tài liệu theo id, bởi vì nó có một giới hạn của khoản boolean tối đa.

Các cơ bản "OR" điều khoản trong Lucene được thực hiện như thế này, giả định rằng lĩnh vực tìm kiếm của bạn được đặt tên là "id":

"id: 1 id: 2 id: 3 id: 4"

thay vì là một "vÀ" truy vấn:

"+ id: 1 + id: 2 + id: 3 + id: 4"

Sử dụng QueryParser tiêu chuẩn và một StringBuilder nên làm điều kỳ diệu cho bạn.

3

Khi bạn thực sự muốn phân tích truy vấn của mình, bạn chỉ cần chọn Trình phân tích và định dạng chính xác cho truy vấn của mình.

StandardAnalyzer không phải là lựa chọn tốt khi bạn lập chỉ mục mọi thứ trừ toàn văn tiếng Anh, đặc biệt là trong trường hợp của bạn! Nó lọc ra con số!

Giải pháp ngắn nhất trong trường hợp của bạn là tạo một trình phân tích mã thông báo tại dấu phân tách và kết hợp đối tượng của bạn thành một chuỗi.

Ví dụ:

Tạo một Tokenizer rằng chia tách tại seperators điển hình và một Analyzer sử dụng nó

using System.IO; 
using System.Linq; 
using Lucene.Net.Analysis; 

namespace Project.Analysis 
{ 
    public class TermTokenizer : LetterTokenizer 
    { 
     // some static separators 
     private static readonly char[] NONTOKEN_CHARS = new char[] { ',', ';', ' ', '\n', '\t' }; 

     protected override bool IsTokenChar(char c) 
     { 
      return !NONTOKEN_CHARS .Contains(c); 
     } 
    } 

    public class LowerCaseTermAnalyzer : Analyzer 
    { 
     public override TokenStream TokenStream(string fieldName, TextReader reader) 
     { 
      return new LowerCaseFilter(new TermTokenizer(reader)); 
     } 
    } 
} 

Sử dụng máy phân tích mới trong phân tích cú pháp của bạn

(Bạn cần phải bao gồm System.Linq)

if (MetaDataID.Length > 0) 
{ 
    // the search term will look like this: "1;5;7" 
    string searchTerm = string.Join(";", MetaDataID); 

    // the query parser uses the new Analyzer 
    QueryParser parser = new QueryParser("MetaData",new LowerCaseTermAnalyzer()); 

    // the parsed search term (only used internally) will look like this: 
    // "MetaData:1 MetaData:5 MetaData:7", which is essentially what you want to achieve 
    completeQuery.Add(new parser.Parse(MetaDataID), BooleanClause.Occur.MUST); 
} 
10

Khi kết hợp các truy vấn Lucene nơi bạn muốn bất kỳ bản ghi chỉ mục nào chứa bất kỳ một trong nhiều giá trị có thể có các tiêu chí bổ sung cũng phải được đáp ứng, tạo nhiều đối tượng truy vấn boolean.

Đối với nhóm đầu tiên của "OR" điều kiện:

BooleanQuery booleanQueryInner = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
Query query3 = new TermQuery(new Term("id", "<id 3>")); 
Query query4 = new TermQuery(new Term("id", "<id 4>")); 
booleanQueryInner.add(query1, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query2, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query3, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query4, BooleanClause.Occur.SHOULD); 

Bây giờ kết hợp với các điều kiện khác trong truy vấn

BooleanQuery booleanQueryOuter = new BooleanQuery(); 
booleanQueryOuter.add(booleanQueryInner, BooleanClause.Occur.MUST); 
booleanQueryOuter.add(boolenaQueryOtherConditions, BooleanClause.Occur.MUST); 

Bây giờ ghi chỉ số sẽ chỉ được trả lại nếu họ đáp ứng một trong những điều kiện trong nhóm "OR" bên trong và cũng đáp ứng các điều kiện trong truy vấn "điều kiện khác".

Các vấn đề liên quan