2009-09-28 29 views
13

Có cách nào để có nhiều tìm kiếm thẻ được triển khai trong CouchDB không? Tôi có tài liệu (bài viết) mỗi với nhiều thẻ. Tôi cần tìm các bài đăng đã được gắn thẻ với một bộ thẻ tùy ý. Tôi phải làm nó như thế nào? Tất nhiên tôi có thể làm điều đó với nhiều cuộc gọi đến một khung nhìn cung cấp cho tôi các tài liệu cho một thẻ và sau đó sắp xếp nó ra trong ứng dụng của tôi nhưng tôi muốn biết liệu có cách nào để đạt được điều tương tự trong vùng xem CouchDB hay không.CouchDB nhiều thẻ

Trả lời

6

Trong các phiên bản CouchDB mới hơn, bạn có thể POST tới một dạng xem với tài liệu JSON có tên là keys, cho phép tra cứu nhiều khóa. Cấu trúc sẽ trông giống như sau:

{"keys": ["first_tag", "second_tag", "third_tag"]} 

Điều này có thể được đăng lên chế độ xem mà bạn đang phát thẻ cho các khóa tương ứng.

Tùy chọn truy vấn này và các tài liệu khác được ghi lại here.

+2

Tôi không chắc chắn liệu đây có phải là cách tốt nhất hay không. Giả sử tôi có một danh sách 15 thẻ riêng biệt có thể được áp dụng trong bất kỳ kết hợp và thứ tự nào khác nhau thì tôi sẽ có 15^14 tổ hợp phím. Tạo và lập chỉ mục tất cả các truy vấn này sẽ tự nó là một nhiệm vụ khó khăn. PS. Toán học không phải là khu vực mạnh nhất của tôi. Đúng nếu tôi đã sai lầm. –

+0

Tất nhiên chúng có thể được sắp xếp và bạn không có nhiều kết hợp. – Luman75

+1

Điều đó hoạt động để truy xuất tất cả các tài liệu có ít nhất một trong các thẻ trong danh sách khóa. Nhưng nếu bạn muốn tìm tất cả các tài liệu có TẤT CẢ các thẻ? –

0

Một cách để làm như được giải thích ở trên bởi Ryan Duffield. Mặc dù nó giải quyết một số truy vấn nhưng nó sẽ trở thành không thể quản lý trong khoảng thời gian. Otherway là sử dụng Full Text Search hiện không được CouchDB hỗ trợ nhưng có một plugin bên ngoài sử dụng Lucene. nhiều hơn ở đây http://wiki.apache.org/couchdb/Full_text_search.

-2

Việc gắn thẻ thực sự có vẻ là một vấn đề rất quan hệ và không chơi tốt với thiết kế của CouchDB. Vì vậy, tôi đã quyết định có một cơ sở dữ liệu nhỏ cho các thẻ trên mysql và có các tài liệu thực tế được lưu trữ tại CouchDB. Điều này cho phép tôi tận dụng tối đa cả hai thế giới. Mặc dù kỹ thuật này có vấn đề liên quan đến đồng bộ hóa, tìm kiếm trên thẻ là một hoạt động hiệu quả trên sql và nội dung không phải là quá nhiều để lo lắng về nhân rộng hoặc sharding. Cảm ơn tất cả các câu trả lời của bạn.

+0

Tôi sẽ không đồng ý với xác nhận này; thẻ hoạt động khá tốt khi được thực hiện đúng trong CouchDB. Tôi sẽ khuyên bạn nên xem một cái gì đó như Sofa cho cảm hứng: http://github.com/jchris/sofa –

+0

Tôi không chắc chắn tại sao điều này là downvoted. ER và các truy vấn liên quan được giải quyết tốt nhất trong một cơ sở dữ liệu quan hệ. – Till

0

Vì vậy, theo như tôi hiểu câu trả lời là KHÔNG. CouchDB không thể truy vấn tài liệu có sự hiện diện của nhiều thẻ (workaround với lucene hoặc mysql không tính, theo cách này chúng tôi đã mất một số tính năng của CouchDB). tin buồn :(

. (có sự hiện diện của nhiều thẻ - có cả A và B, không phải A hoặc B)

UPD Có thể nhưng với những hạn chế để chỉ có 2-3 thẻ

!.

http://wiki.apache.org/couchdb/EntityRelationship

Truy vấn bởi nhiều phím

Một số ứng dụng cần để xem các ngã tư o f thực thể có nhiều khóa. Trong ví dụ trên, đây sẽ là truy vấn cho các liên hệ ở cả nhóm "Bạn bè" và "Đồng nghiệp". Cách thẳng tiến nhất để xử lý tình huống này là truy vấn một trong các khóa và sau đó lọc theo phần còn lại của các phím ở phía máy khách. Nếu các tần số chính thay đổi rất nhiều, nó cũng có thể đáng giá để thực hiện cuộc gọi ban đầu để xác định khóa có tần số thấp nhất và sử dụng để lấy danh sách tài liệu ban đầu từ cơ sở dữ liệu.

Nếu đây không phải là một lựa chọn tốt, có thể lập chỉ mục các tổ hợp phím, mặc dù tăng trưởng của chỉ mục cho một tài liệu nhất định sẽ theo cấp số nhân với số khóa của nó. Tuy nhiên, đối với các bộ khóa nhỏ-ish, đây là một tùy chọn, vì các phím có thể được đặt hàng, và các khóa là tiền tố của một khóa lớn hơn có thể được bỏ qua.Ví dụ, đối với tổ hợp phím [1 2 3] các tổ hợp phím có thể là [1] [2] [3] [1 2] [1 3] [2 3] [1 2 3] Tuy nhiên, chỉ mục chỉ cần chứa các phím [3] [1 3] [2 3] [1 2 3] kể từ (ví dụ) các tài liệu phù hợp với các phím [1 2] có thể thu được với một truy vấn cho startkey = [1,2, null] và endkey = [1,2, {}] Số lượng mục nhập chỉ mục sẽ là số khóa 2^(n-1).

Tùy chọn cuối cùng là sử dụng một chỉ mục riêng biệt, chẳng hạn như couchdb-lucene để trợ giúp với các truy vấn như vậy.

1

Tôi nghĩ rằng sau đây sẽ cung cấp cho bạn một thuật toán hơi phức tạp nhưng chắc chắn - tức là nó tìm thấy kết quả đầu tiên nhanh chóng, ngay cả khi bạn có nhiều tài liệu. Nó có thể sẽ không hoạt động tốt trong thực tế :(

Index các tài liệu theo từng thẻ duy nhất và có id tài liệu:

 
[<some tag>, <document id>] 

Ví dụ cho các tài liệu ghi lại

  • docid1 với các thẻ [xanh , xanh lá cây, đỏ]
  • docid2 với các thẻ [xanh, vàng]

bạn nhận được

 
['blue', 'docid1'] 
['blue', 'docid2'] 
['green', 'docid1'] 
['red', 'docid1'] 
['yellow', 'docid2'] 

Bây giờ cho mỗi thẻ bạn muốn tìm kiếm, bạn mở tìm kiếm song song bắt đầu tại [tag, ...].

Đối với mỗi thẻ bạn duy trì vị trí tìm kiếm hiện tại. Nếu tài liệu ở tất cả các tìm kiếm của bạn phù hợp, bạn đã tìm thấy kết quả phù hợp. Nếu chúng không khớp, hãy thử bỏ qua ít nhất là id tài liệu cao nhất thông qua tìm kiếm theo phạm vi. Nói lại.

[Đó là cơ bản một tham gia.]

Các nhảy là về mặt lý thuyết nhanh chóng: Chúng tôi có một chỉ số để tìm các tài liệu này. Thực tế, nó có thể chậm vì tất cả các chuyến đi vòng đến máy chủ. Nó sẽ là tốt đẹp để có thể offload thuật toán đó đến một chức năng thực hiện trên máy chủ. Điều đó có thể không?