2012-02-01 29 views
7

Tôi đang sử dụng trình phân tích quả cầu tuyết để chặn các tiêu đề của nhiều tài liệu. Tất cả mọi thứ hoạt động tốt, nhưng họ là một số quirks.Sử dụng kết hợp các ký tự đại diện và thân cây

Ví dụ:

Tìm kiếm "valv", "van" hoặc "van" trả về cùng một số kết quả. Điều này có ý nghĩa vì phân tích quả cầu tuyết làm giảm mọi thứ xuống "valv".

Tôi gặp sự cố khi sử dụng ký tự đại diện. Tìm kiếm "van *" hoặc "van *" không trả lại bất kỳ kết quả nào. Tìm kiếm "valv *" hoạt động như mong đợi.

Tôi hiểu tại sao điều này xảy ra, nhưng tôi không biết cách khắc phục.

Tôi đã nghĩ đến việc viết một trình phân tích lưu trữ các mã thông báo gốc và không có gốc. Về cơ bản áp dụng hai máy phân tích và kết hợp hai luồng mã thông báo. Nhưng tôi không chắc đây có phải là giải pháp thực tế hay không.

Tôi cũng đã nghĩ về việc sử dụng AnalyzingQueryParser, nhưng tôi không biết cách áp dụng điều này cho truy vấn đa năng. Ngoài ra, việc sử dụng AnalyzingQueryParser sẽ trả về kết quả cho "van" khi tìm kiếm "van *" và đó không phải là hành vi mong đợi.

Có cách nào "ưa thích" sử dụng cả hai ký tự đại diện và thuật toán bắt nguồn không?

Trả lời

7

tôi đã sử dụng 2 phương pháp khác nhau để giải quyết việc này trước khi

  1. Sử dụng hai lĩnh vực, một trong đó có những điều khoản bắt nguồn, một trong những khác có chứa từ ngữ được tạo ra bởi tiếng nói, các StandardAnalyzer. Khi bạn phân tích cú pháp truy vấn tìm kiếm nếu truy vấn tìm kiếm theo ký tự đại diện của nó trong trường "chuẩn", nếu không sử dụng trường có cụm từ bắt nguồn. Điều này có thể khó sử dụng hơn nếu bạn có người dùng nhập truy vấn của họ trực tiếp vào QueryParser của Lucene.

  2. Viết mã thông báo phân tích tùy chỉnh và chỉ mục chồng chéo. Về cơ bản nó bao gồm lập chỉ mục từ gốc và gốc tại cùng một vị trí trong chỉ mục bằng cách sử dụng PositionIncrementAttribute. Bạn có thể xem xét SynonymFilter để biết ví dụ về cách sử dụng chính xác PositionIncrementAttribute.

I Ưu tiên giải pháp # 2.

+0

+1 cho giải pháp thứ hai, đó là cách tự nhiên nhất để làm điều này. –

1

Tôi không nghĩ rằng có cách dễ dàng (và chính xác) để thực hiện việc này.

Giải pháp của tôi sẽ viết một trình phân tích truy vấn tùy chỉnh tìm thấy các chuỗi dài nhất phổ biến với các cụm từ trong chỉ mục và tiêu chí tìm kiếm của bạn.

class MyQueryParser : Lucene.Net.QueryParsers.QueryParser 
{ 
    IndexReader _reader; 
    Analyzer _analyzer; 

    public MyQueryParser(string field, Analyzer analyzer,IndexReader indexReader) : base(field, analyzer) 
    { 
     _analyzer = analyzer; 
     _reader = indexReader; 
    } 

    public override Query GetPrefixQuery(string field, string termStr) 
    { 
     for(string longestStr = termStr; longestStr.Length>2; longestStr = longestStr.Substring(0,longestStr.Length-1)) 
     { 
      TermEnum te = _reader.Terms(new Term(field, longestStr)); 
      Term term = te.Term(); 
      te.Close(); 
      if (term != null && term.Field() == field && term.Text().StartsWith(longestStr)) 
      { 
       return base.GetPrefixQuery(field, longestStr); 
      } 
     } 

     return base.GetPrefixQuery(field, termStr); 
    } 
} 

bạn cũng có thể thử gọi phân tích của bạn trong GetPrefixQuery mà không được gọi cho PrefixQuery s

TokenStream ts = _analyzer.TokenStream(field, new StringReader(termStr)); 
Lucene.Net.Analysis.Token token = ts.Next(); 
var termstring = token.TermText(); 
ts.Close(); 
return base.GetPrefixQuery(field, termstring); 

Nhưng, hãy nhớ rằng bạn luôn có thể tìm thấy một trường hợp kết quả trả về là không đúng. Đây là lý do tại sao Lucene không tính đến các máy phân tích khi sử dụng các ký tự đại diện.

+0

Tôi thực sự muốn tìm cách kết hợp hai mã thông báo để tôi có thể có một bộ mã thông báo gốc và không bắt nguồn từ ... Tôi sẽ xem xét điều này một chút. Tôi sẽ cập nhật nếu tôi tìm cách. – SharpBarb

0

Ý tưởng tiềm năng duy nhất mà tôi vượt ra ngoài các câu trả lời khác là sử dụng tính năng tháo dỡ đối với hai trường, vì vậy bạn chỉ có thể đặt trọng số tương đối của hai trường. Các chỉ báo trước là một số phiên bản của dismax đã không xử lý ký tự đại diện, và một số phân tích cú pháp là Solr cụ thể.

1

Đây là giải pháp đơn giản nhất và nó sẽ làm việc -

Thêm solr.KeywordRepeatFilterFactory trong 'index' phân tích của bạn.

http://lucene.apache.org/core/4_8_0/analyzers-common/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.html

Ngoài ra thêm RemoveDuplicatesTokenFilterFactory vào cuối của 'index' phân tích

Bây giờ trong chỉ số của bạn, bạn sẽ luôn luôn có sự bắt nguồn và không bắt nguồn hình thức cho mỗi mã thông báo vị trí tương đương và bạn tốt để đi.

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