2008-08-20 6 views
5

Tôi muốn sử dụng Lucene (cụ thể là Lucene.NET) để tìm kiếm các miền địa chỉ email.Sử dụng Lucene để tìm kiếm địa chỉ email

Ví dụ: Tôi muốn tìm kiếm "@ gmail.com" để tìm tất cả email được gửi tới địa chỉ gmail.

Chạy truy vấn Lucene cho "*@gmail.com" dẫn đến lỗi, dấu hoa thị không thể ở đầu truy vấn. Chạy truy vấn cho "@ gmail.com" không trả lại bất kỳ kết quả nào phù hợp, bởi vì "[email protected]" được xem như một từ nguyên và bạn không thể tìm kiếm chỉ một phần của một từ.

Làm thế nào tôi có thể làm điều này?

Trả lời

10

Không ai đưa ra câu trả lời thỏa đáng, vì vậy chúng tôi bắt đầu tìm hiểu về tài liệu Lucene và phát hiện ra chúng tôi có thể thực hiện việc này bằng cách sử dụng Trình phân tích và Mã thông báo tùy chỉnh.

Câu trả lời là: tạo WhitespaceAndAtSymbolTokenizer và WhitespaceAndAtSymbolAnalyzer, sau đó tạo lại chỉ mục của bạn bằng cách sử dụng trình phân tích này. Khi bạn thực hiện việc này, tìm kiếm "@ gmail.com" sẽ trả về tất cả các địa chỉ gmail, bởi vì nó được xem như một từ riêng biệt nhờ vào Tokenizer mà chúng tôi vừa tạo.

Dưới đây là mã nguồn, nó thực sự rất đơn giản:

class WhitespaceAndAtSymbolTokenizer : CharTokenizer 
{ 
    public WhitespaceAndAtSymbolTokenizer(TextReader input) 
     : base(input) 
    { 
    } 

    protected override bool IsTokenChar(char c) 
    { 
     // Make whitespace characters and the @ symbol be indicators of new words. 
     return !(char.IsWhiteSpace(c) || c == '@'); 
    } 
} 


internal class WhitespaceAndAtSymbolAnalyzer : Analyzer 
{ 
    public override TokenStream TokenStream(string fieldName, TextReader reader) 
    { 
     return new WhitespaceAndAtSymbolTokenizer(reader); 
    } 
} 

Vậy là xong! Bây giờ bạn chỉ cần xây dựng lại chỉ mục của bạn và thực hiện tất cả các tìm kiếm bằng cách sử dụng Bộ phân tích mới này. Ví dụ, để viết các tài liệu chỉ mục của bạn:

IndexWriter index = new IndexWriter(indexDirectory, new WhitespaceAndAtSymbolAnalyzer()); 
index.AddDocument(myDocument); 

tìm kiếm Performing nên sử dụng máy phân tích cũng như:

IndexSearcher searcher = new IndexSearcher(indexDirectory); 
Query query = new QueryParser("TheFieldNameToSearch", new WhitespaceAndAtSymbolAnalyzer()).Parse("@gmail.com"); 
Hits hits = query.Search(query); 
+0

Tôi cũng sẽ chuyển tokenizer thông qua một LowerCaseFilter, hoặc có lẽ một LowerCaseFilter tùy chỉnh mà sẽ chỉ chữ thường @ GmAil.COM token –

5

Tôi thấy bạn có giải pháp của bạn, nhưng tôi có thể tránh được điều này và bổ sung thêm một lĩnh vực vào các tài liệu mà bạn đang lập chỉ mục được gọi là email_domain, trong đó tôi sẽ thêm miền được phân tích cú pháp của địa chỉ email. Nó có thể âm thanh ngớ ngẩn, nhưng số lượng lưu trữ liên quan đến điều này là khá tối thiểu. Nếu bạn cảm thấy muốn trở nên giàu có hơn, hãy nói một số miền có nhiều tên miền phụ, thay vào đó bạn có thể tạo một trường mà miền bị đảo ngược đi, vì vậy bạn nên lưu trữ com.gmail, com.company.department hoặc ae.eim để bạn có thể tìm thấy tất cả các địa chỉ liên quan đến United Arab Emirates có truy vấn tiền tố 'ae'.

0

Bạn có thể một lĩnh vực riêng biệt mà chỉ số địa chỉ email đảo ngược: Index '[email protected]' là '[email protected]' nào cho phép bạn thực hiện một truy vấn cho "[email protected]*"

+0

Hmm. Điều đó nghe có vẻ rất đáng sợ. –

2

Ngoài ra còn có setAllowLeadingWildcard

Nhưng hãy cẩn thận . Điều này có thể nhận được rất hiệu suất đắt tiền (đó là lý do tại sao nó bị vô hiệu hóa theo mặc định). Có thể trong một số trường hợp, đây sẽ là một giải pháp dễ dàng, nhưng tôi cũng muốn có một Tokenizer tùy chỉnh như được nêu bởi Judah Himango.