2010-07-22 36 views
29

Tôi đang cố gắng sử dụng CouchDB cho ứng dụng mới và tôi cần tạo chế độ xem sắp xếp theo nhiều trường và cũng lọc theo nhiều trường. Dưới đây là một tài liệu ví dụ, tôi đã rời khỏi _id và _rev để lưu bản thân một số cách gõ.Sắp xếp và lọc CouchDB trong cùng một chế độ xem

{ 
    "title": "My Document", 
    "date": 1279816057, 
    "ranking": 5, 
    "category": "fun", 
    "tags": [ 
     "couchdb", 
     "technology" 
    ], 
} 

Từ tài liệu, tôi đã biết rằng tôi có thể dễ dàng tạo chế độ xem sắp xếp theo trường như xếp hạng.

function(doc) { 
    emit(doc.ranking, doc); 
} 

Tôi cũng đã học được rằng tôi có thể dễ dàng lọc theo các lĩnh vực như loại

function(doc) { 
    emit(doc.category, doc); 
} 

http://127.0.0.1:5984/database/_design/filter/_view/filter?key=%22fun%22 

Vấn đề của tôi là tôi cần phải làm một loạt những điều này tất cả cùng một lúc. Tôi muốn lọc dựa trên danh mục và cũng có thẻ. Tôi sẽ có thể lọc xuống chỉ các tài liệu có danh mục "vui nhộn" và thẻ "couchdb". Tôi muốn sắp xếp các kết quả được lọc theo xếp hạng theo thứ tự giảm dần, sau đó theo ngày theo thứ tự tăng dần, sau đó theo tiêu đề theo thứ tự bảng chữ cái.

Tôi làm cách nào để tạo một chế độ xem thực hiện tất cả sắp xếp và lọc đó được kết hợp?

Trả lời

45

Để phát nhiều hơn một phần dữ liệu trong một khóa, bạn sẽ muốn đọc trên Complex Keys. Bạn sẽ rất có thể sẽ kết thúc emit() 'nhập khóa là một mảng được tạo thành từ danh mục và thẻ. Ví dụ:

function(doc) { 
    for(var i = 0; i < doc.tags.length; i++) 
    emit([doc.category, doc.tags[i]], doc); 
} 

Bây giờ, khi bạn truy vấn ?key=["fun", "couchdb"] bạn sẽ nhận được tất cả các mục trong danh mục thú vị được gắn thẻ "couchdb". Hoặc nếu bạn muốn tất cả các mục trong danh mục vui nhộn, bất kể thẻ của chúng, thì bạn có thể truy vấn với một phạm vi: ?startkey=["fun"]&endkey=["fun", {}]. Chỉ cần nhớ, nếu mặt hàng của bạn có nhiều thẻ, bạn sẽ nhận được nhiều lần trong kết quả (vì bạn emit() 'd tài liệu một lần cho mỗi thẻ).

Để thực hiện thêm bước phân loại theo xếp hạng, ngày tháng và tiêu đề, bạn sẽ thêm hai phần tử vào mảng của mình: số nguyên và thứ hạng, ngày hoặc tiêu đề. Hãy nhớ rằng, bạn có thể emit() nhiều lần cho mỗi chức năng bản đồ. Một chức năng ví dụ bản đồ ...

function(doc) { 
    for(var i = 0; i < doc.tags.length; i++) 
    { 
    emit([doc.category, doc.tags[i], 0, doc.ranking], doc); 
    emit([doc.category, doc.tags[i], 1, doc.title], doc); 
    emit([doc.category, doc.tags[i], 2, doc.date], doc); 
    } 
} 

Bây giờ cấu trúc quan trọng của bạn là: ["category", "tag", 0 ... 2, rank/title/date]

Bạn đang cơ bản nhóm tất cả các bảng xếp hạng dưới 0, tiêu đề dưới 1, và ngày dưới 2. Tất nhiên, bạn đang truyền tải rất nhiều dữ liệu, vì vậy bạn có thể tách từng nhóm này ra thành chế độ xem riêng trong tài liệu thiết kế của bạn hoặc chỉ trả về giá trị _id của tài liệu làm giá trị (emit([ ...], doc._id);).

Nhận tất cả mọi thứ trong hạng mục "vui vẻ" với "couchdb" tag (tăng dần):

?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}] 

Nhận tất cả mọi thứ trong hạng mục "vui vẻ" với "couchdb" tag (giảm dần):

?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true 

Nhận chỉ bảng xếp hạng trong hạng mục vui vẻ với thẻ couchdb (tăng dần):

?startkey=["fun", "couchdb", 0]&endkey=["fun", "couchdb", 0, {}]

Nhận chỉ bảng xếp hạng trong hạng mục "vui vẻ" với "couchdb" tag (giảm dần):

?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true 

Tôi hy vọng điều này sẽ giúp. Các phím phức tạp bắt đầu thực sự thể hiện mức độ mạnh mẽ của Map/Reduce khi cắt và dicing dữ liệu.

Chúc mừng.

+0

Cảm ơn điều này thực sự hữu ích, nhưng tôi chỉ cần trợ giúp thêm một chút. Vì nó phát ra cùng một tài liệu nhiều lần, làm thế nào để tôi nhận được nó chỉ cho tôi mỗi tài liệu một lần? – Apreche

+1

Bạn không thể, trừ khi bạn chia nhỏ từng nhóm này thành chế độ xem của riêng họ. Ví dụ,/_design/articles/_view/byRanking,/_design/articles/_view/byDate, vv Nếu bạn muốn giữ mọi thứ trong một khung nhìn này, thì bạn sẽ phải quản lý dữ liệu trong máy khách của bạn. Hoặc bạn có thể làm theo những gì tôi đã nói về chỉ trả về _id hoặc null của tài liệu làm giá trị, khi bạn có thể thực hiện cuộc gọi thứ hai để nhận tài liệu một lần. –

+0

Ồ, đợi đã, đừng bận tâm. Tôi đã hiểu rồi. Tôi nghĩ rằng bạn hơi hiểu lầm những gì tôi muốn. Tôi muốn sắp xếp theo xếp hạng, ngày tháng và tiêu đề cùng một lúc. Trong SQL nó sẽ là "thứ tự bằng cách xếp hạng asc, ngày desc, tiêu đề asc" Tôi có thể làm điều này bằng cách làm chỉ một phát ra và sử dụng khóa khởi động và khóa để lọc và thứ tự sẽ được thực hiện. Cảm ơn! – Apreche

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