2012-01-10 35 views
6

Ứng dụng Grails của tôi đang sử dụng plugin có thể tìm kiếm, được xây dựng trên Compass và Lucene để cung cấp chức năng tìm kiếm. Tôi có hai lớp học có thể tìm kiếm, nói tác giả và sách. Tôi đã ánh xạ các lớp này vào chỉ mục tìm kiếm để chỉ có thể tìm kiếm một số trường nhất định.truy vấn plugin tìm kiếm grails

Để thực hiện tìm kiếm trên cả hai lớp tôi chỉ đơn giản gọi

def results = searchableService.search(query) 

Một trong những tính năng tốt đẹp của việc tìm kiếm trên cả hai lớp cùng một lúc, đó là đối tượng results bao gồm siêu dữ liệu về số lượng kết quả bao gồm, số lượng kết quả có sẵn, chi tiết phân trang, v.v.

Gần đây tôi đã thêm cờ boolean approved vào lớp Sách và tôi không bao giờ muốn sách không được chấp thuận xuất hiện trong kết quả tìm kiếm. Một tùy chọn là thay thế cuộc gọi ở trên bằng:

def bookResults = Book.search(query + " approved:1") 
def authorResults = Author.search(query) 

Tuy nhiên, bây giờ tôi cần tìm cách kết hợp siêu dữ liệu cho cả hai kết quả, có khả năng phức tạp (đặc biệt là phân trang).

Có cách nào để tìm kiếm trên Sách và Tác giả chỉ bằng một truy vấn, nhưng chỉ trả lại sách được phê duyệt?

Trả lời

4

Tôi đã tạo một ứng dụng thử nghiệm và đi đến giải pháp sau. có thể nó sẽ giúp ...

nếu tài sản approved chỉ có các tiểu bang 01, các truy vấn sau đây sẽ làm việc:

def results = searchableService.search(
    "(${query} AND approved:1) OR (${query} -approved:0 -approved:1)" 
) 

Tôi đoán đây có thể được thay đổi công một cách tốt nhất nếu bạn không sử dụng QueryParser nhưng BooleanQueryBuilder.

BTW: nếu bạn thêm một phương pháp như

String getType() { "Book" } 

String getType() { "Author" } 

Để tên miền của bạn, thậm chí bạn có thể cấu hình tìm kiếm của bạn để làm điều đó như thế này

def results = searchableService.search(
    "(${query} AND approved:1) OR (${query} AND type:Author)" 
) 
+0

Tôi ngưỡng mộ sự kiên trì của bạn. Giải pháp trên dường như hoạt động, cảm ơn rất nhiều! –

+0

:-) hy vọng nắm bắt được tiền thưởng ... – rdmueller

6

Bạn có muốn tìm tác giả hoặc bạn muốn tìm sách với một tác giả cụ thể không?

Nếu bạn muốn tìm những cuốn sách có một tác giả nào đó, bạn có thể cấu hình các lớp miền của bạn theo cách sau:

class Author { 
    String name 
    ... 

    static searchable = { 
     root false 
    }  
} 

này sẽ cho kết quả không bao gồm các tác giả từ searchableService.search(query) -result và bạn sẽ tìm thấy tên trường như $/Book/Author/name trong chỉ mục của bạn. (sử dụng luke để kiểm tra chỉ mục của bạn: http://code.google.com/p/luke/).

Bạn có thể thay đổi tên của các lĩnh vực này bằng cách cấu hình một tốt hơn prefix trong Sách-lớp học của bạn:

class Book { 
    String name 
    Author author 
    ... 

    static searchable = { 
     author component: [prefix: 'author'] 
    }  
} 

này sẽ thay đổi tên của lĩnh vực này trong chỉ mục để bookauthor.

Nếu bây giờ bạn tìm kiếm với searchableService.search(query), bạn sẽ tìm thấy tất cả các sách có tên sách hoặc tên tác giả chứa cụm từ tìm kiếm. Bạn thậm chí có thể hạn chế tìm kiếm đối với một tác giả cụ thể bằng cách sử dụng cú pháp authorname:xyz.


Nếu bạn thực sự muốn để pha trộn các kết quả tìm kiếm, tôi chỉ biết giải pháp bạn đã đề cập: trộn cả hai kết quả với mã riêng của bạn, nhưng tôi đoán nó sẽ được khó khăn để pha trộn các điểm trong những hit trong một cách tốt.

Update để trả lời của bạn: Đây là mã pagination của tôi ...

.gsp:

<div class="pagination"> 
    <g:paginate total="${resultsTotal}" params="[q: params.q]"/> 
</div> 

điều khiển:

result = searchableService.search(params.q, params) 
[ 
    resultList: result.results, 
    resultsTotal: result.total 
] 

Vì vậy, nếu bạn chỉ cần kết hợp các kết quả của hai tìm kiếm của bạn và thêm result.total giây, điều này có thể phù hợp với bạn.

+0

Tôi muốn có thể tìm sách và tác giả bằng một truy vấn, nhưng không bao giờ bao gồm cả b ooks trong kết quả. Vấn đề với việc thực hiện 2 truy vấn là rất khó để kết hợp 2 bộ siêu dữ liệu thành một tập hợp duy nhất. Ví dụ: nếu tôi có 2 trang kết quả sách và 2 trang kết quả tác giả, điều đó không nhất thiết có nghĩa là tôi có 4 trang kết quả trong tổng số –

+0

Xin lỗi, tôi đoán tôi đã bỏ lỡ điều gì đó ở đây. Không phải là trường hợp nếu bạn có 15 kết quả sách và 17 kết quả tác giả, bạn sẽ luôn có 32 kết quả cùng nhau -> 4 trang (với 10 kết quả mỗi) – rdmueller

+0

Có, nhưng nếu tôi có 11 kết quả sách (2 trang) và 11 tác giả kết quả (2 trang), sau đó nếu tôi kết hợp các kết quả tôi có thể phù hợp với chúng thành 3 trang. –

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