2010-07-22 21 views
14

Ký tự đại diện * chỉ có thể được sử dụng ở cuối từ, như user*.Làm thế nào để truy vấn lucene với toán tử "like"?

Tôi muốn truy vấn giống như %user%, cách thực hiện điều đó?

+0

vấn đề Hơi tương tự: [http://stackoverflow.com/questions/468279/lucene-net-leading-wildcard-character-throws-an-error](http:// stackoverflow.com/questions/468279/lucene-net-leading-wildcard-character-throws-an-error) – devson

Trả lời

9

Lucene cung cấp ReverseStringFilter cho phép thực hiện tìm kiếm theo ký tự đại diện hàng đầu như * người dùng. Nó hoạt động bằng cách lập chỉ mục tất cả các từ theo thứ tự ngược lại.

Nhưng tôi nghĩ không có cách nào để làm điều gì đó tương tự như 'LIKE% user%'.

+2

Thú vị. Nó, có hiệu lực, có nghĩa là bạn cần phải thiết lập chỉ mục của bạn trước để cho phép các ký tự đại diện hàng đầu. Và từ việc nhìn vào lỗi (https://issues.apache.org/jira/browse/LUCENE-1398), có vẻ như bạn chỉ có thể chỉ định một ký tự đại diện hàng đầu, nhưng không chỉ một ký tự đại diện trong cùng một cụm từ (vì sau đó bạn đang trở lại cùng một vấn đề). – Jon

6

Kể từ Lucene 2.1 bạn có thể sử dụng

QueryParser.setAllowLeadingWildcard(true); 

nhưng điều này có thể giết chết hiệu suất. LuceneFAQ có thêm một số thông tin cho việc này.

3

Khi bạn nghĩ về nó, nó không phải là hoàn toàn không ngạc nhiên rằng sự hỗ trợ của lucene cho ký tự đại diện là (thường) bị giới hạn trong một ký tự đại diện ở cuối của một mẫu từ.

Công cụ tìm kiếm từ khóa hoạt động bằng cách tạo chỉ mục đảo ngược của tất cả các từ trong kho văn bản, được sắp xếp theo thứ tự từ. Khi bạn thực hiện tìm kiếm không theo ký tự đại diện thông thường, công cụ sẽ sử dụng thực tế là các mục nhập chỉ mục được sắp xếp để xác định mục nhập hoặc mục nhập cho từ của bạn trong các bước O(logN) trong đó N là số từ hoặc mục nhập. Đối với một mẫu từ có ký tự đại diện hậu tố, điều tương tự cũng xảy ra để tìm từ khớp đầu tiên và các kết quả khớp khác được tìm thấy bằng cách quét các mục nhập cho đến khi phần cố định của mẫu không còn khớp.

Tuy nhiên, đối với một mẫu chữ với một tiền tố wildcard một hậu tố ký tự đại diện, động cơ sẽ phải nhìn vào tất cả mục trong chỉ mục. Điều này sẽ là O(N) ... trừ khi động cơ đã xây dựng toàn bộ các chỉ mục phụ để kết hợp các chất nền của từ. (Và điều đó sẽ làm cho việc lập chỉ mục đắt hơn rất nhiều). Và đối với các mẫu phức tạp hơn (ví dụ: regexes), vấn đề sẽ còn tồi tệ hơn đối với công cụ tìm kiếm.

14

Sự cố với truy vấn LIKE là chúng là expensive về thời gian thực hiện. Bạn có thể thiết lập QueryParser để cho phép các kí hiệu hàng đầu với những điều sau đây:

QueryParser.setAllowLeadingWildcard(true)

Và điều này sẽ cho phép bạn thực hiện tìm kiếm như:

*user*

Nhưng điều này sẽ mất nhiều thời gian để thực hiện . Đôi khi, khi mọi người nói rằng họ muốn có truy vấn LIKE, điều họ thực sự muốn là fuzzyquery. Điều này sẽ cho phép bạn thực hiện tìm kiếm sau:

user~

nào sẽ phù hợp với các điều khoản usersfuser. Bạn có thể chỉ định khoảng cách chỉnh sửa giữa cụm từ trong truy vấn của mình và các cụm từ bạn muốn đối sánh bằng giá trị nổi giữa 0 và 1. Ví dụ: user~0.8 sẽ khớp với nhiều cụm từ hơn user~0.5.

Tôi khuyên bạn cũng nên xem regex query, hỗ trợ cú pháp biểu thức chính quy cho tìm kiếm Lucene. Nó có thể gần hơn với những gì bạn thực sự cần.Có lẽ cái gì đó như:

.*user.*

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