2008-10-12 16 views
6

Tôi biết có thể có được các điều khoản hàng đầu trong chỉ mục Lucene, nhưng có cách nào để có được các điều khoản hàng đầu dựa trên một tập hợp con của chỉ mục Lucene không?Làm cách nào để có được các điều khoản hàng đầu cho một tập hợp con các tài liệu trong chỉ mục Lucene?

I.e. Các thuật ngữ hàng đầu trong Chỉ mục cho tài liệu trong một phạm vi ngày nhất định là gì?

Trả lời

5

Lý tưởng nhất là có tiện ích ở đâu đó để thực hiện việc này, nhưng tôi không biết. Tuy nhiên, nó không quá khó để làm điều này "bằng tay" một cách hợp lý hiệu quả. Tôi giả sử rằng bạn đã có đối tượng Query và/hoặc Filter mà bạn có thể sử dụng để xác định tập hợp con quan tâm.

Trước tiên, hãy tạo danh sách trong bộ nhớ của tất cả ID tài liệu trong tập hợp con chỉ mục của bạn. Bạn có thể sử dụng IndexSearcher.search(Query, Filter, HitCollector) để thực hiện việc này rất nhanh chóng; HitCollectordocumentation bao gồm ví dụ có vẻ như nó phải hoạt động hoặc bạn có thể sử dụng một số vùng chứa khác để lưu trữ ID tài liệu của mình.

Tiếp theo, khởi tạo một HashMap rỗng (hoặc bất kỳ thứ gì) để ánh xạ các cụm từ vào tổng tần số và điền bản đồ bằng cách gọi một trong các phương thức IndexReader.getTermFreqVector cho mọi tài liệu và trường quan tâm. Dạng ba đối số có vẻ đơn giản hơn, nhưng có lẽ là tốt. Đối với biểu mẫu ba đối số, bạn sẽ thực hiện một phương thức TermVectorMapper có phương pháp map kiểm tra nếu term nằm trong bản đồ, liên kết nó với frequency nếu không, hoặc thêm frequency vào giá trị hiện tại nếu có. Hãy chắc chắn sử dụng cùng một đối tượng TermVectorMapper trên tất cả các cuộc gọi đến getTermFreqVector trong thẻ này, thay vì khởi tạo một đối tượng mới cho từng tài liệu trong vòng lặp. Bạn cũng có thể tăng tốc độ lên một chút bằng cách ghi đè isIgnoringPositions()isIgnoringOffsets(); đối tượng của bạn phải trả lại true cho cả hai đối tượng đó. Có vẻ như TermVectorMapper của bạn cũng có thể bị buộc phải xác định phương thức setExpectations, nhưng phương pháp đó không cần phải làm gì cả.

Khi bạn đã xây dựng bản đồ của mình, chỉ cần sắp xếp các mục bản đồ theo tần suất giảm dần và đọc trừ nhiều cụm từ hàng đầu mà bạn thích. Nếu bạn biết trước bao nhiêu cụm từ bạn muốn, bạn có thể muốn thực hiện một số thuật toán dựa trên heap ưa thích để tìm kiếm các mục k hàng đầu trong thời gian tuyến tính thay vì sử dụng một kiểu chữ O (n log n) . Tôi hình dung rằng loại đồng bằng cũ sẽ rất nhanh trong thực tế. Nhưng nó là tùy thuộc vào bạn.

Nếu muốn, bạn có thể kết hợp hai giai đoạn đầu tiên bằng cách trực tiếp HitCollector gọi trực tiếp getTermFreqVector. Điều này chắc chắn sẽ tạo ra kết quả chính xác như nhau, và trực giác dường như đơn giản và tốt hơn, nhưng các tài liệu dường như cảnh báo rằng làm như vậy có khả năng chậm hơn một chút so với phương pháp hai bước (trên cùng một trang với ví dụ HitCollector) ở trên). Hoặc tôi có thể hiểu sai cảnh báo của họ. Nếu bạn cảm thấy đầy tham vọng, bạn có thể thử cả hai cách, so sánh và cho chúng tôi biết.

+1

Điều này có thực sự rất chậm, đặc biệt nếu có nhiều lần truy cập? – jjxtra

0

Tính toán TermVectors sẽ hoạt động, nhưng sẽ chậm nếu có nhiều tài liệu để lặp lại. Cũng lưu ý nếu bạn có nghĩa là docFreq theo thuật ngữ hàng đầu, sau đó không sử dụng số đếm trong TermFreqVector chỉ cần đếm các thuật ngữ dưới dạng nhị phân.

Hoặc, bạn có thể lặp lại các cụm từ như số lượng khía cạnh. Sử dụng một số cached filter cho mỗi cụm từ; BitSets của chúng có thể được sử dụng cho số lượng giao lộ nhanh.

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