Я пытаюсь использовать CouchDB для нового приложения, и я должен создать представление, что виды несколькими полями и также фильтруют несколькими полями. Вот документ в качестве примера, я не учел _id и _rev для сохранения меня некоторый ввод.
{
"title": "My Document",
"date": 1279816057,
"ranking": 5,
"category": "fun",
"tags": [
"couchdb",
"technology"
],
}
Из документации я узнал, что могу легко создать представление что виды полем, такие как рейтинг.
function(doc) {
emit(doc.ranking, doc);
}
Я также узнал, что могу легко отфильтровать полями, такими как категория
function(doc) {
emit(doc.category, doc);
}
http://127.0.0.1:5984/database/_design/filter/_view/filter?key=%22fun%22
Моя проблема состоит в том, что я должен сделать набор этих вещей все одновременно. Я хочу отфильтровать на основе категории и также отметить. Я должен смочь отфильтровать только к документам с категорией "забавы" и тегом "couchdb". Я хочу отсортировать те фильтрованные результаты путем рейтинга в порядке убывания, затем по дате в порядке возрастания, затем заголовком в алфавитном порядке.
Как я могу создать одно представление, которое делает всю ту сортировку и объединенную фильтрацию?
Чтобы передать более одного фрагмента данных в ключе, прочтите статью Комплексные ключи . Скорее всего, вы получите emit ()
с ключом, который представляет собой массив, состоящий из категории и тега. Например ...
function(doc) {
for(var i = 0; i < doc.tags.length; i++)
emit([doc.category, doc.tags[i]], doc);
}
Теперь, когда вы запрашиваете ? Key = ["fun", "couchdb"]
, вы получите все элементы в категории развлечений, помеченные как couchdb. Или, если вы хотите, чтобы все элементы в категории развлечения, независимо от их тега, вы можете запросить с диапазоном: ? Startkey = ["fun"] & endkey = ["fun", {}]
. Просто помните, что если ваш элемент имеет несколько тегов, вы получите его несколько раз в результатах (потому что вы emit ()
создавали документ один раз для каждого тега).
Чтобы перейти на дополнительный этап сортировки по рейтингу, дате и заголовку, вы добавите в свой массив еще два элемента: целое число и либо рейтинг, либо дату, либо заголовок. Помните, что вы можете emit ()
более одного раза для каждой функции карты. Пример функции карты ...
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);
}
}
Теперь ваша структура ключей: ["категория", "тег", 0 ... 2, ранг / название / дата]
Вы в основном группируете все рейтинг ниже 0, заголовки ниже 1 и даты ниже 2. Конечно, вы передаете много данных, поэтому вы можете либо разбить каждую из этих групп на отдельное представление в своем проектном документе, либо вернуть только документ _id
в качестве значения ( emit ([...], doc._id);
).
Получите все в категории «развлечения» с помощью тега «couchdb» (по возрастанию):
?startkey=["fun", "couchdb"]&endkey=["fun", "couchdb", {}, {}]
Получите все в категории «развлечения» с помощью тега «couchdb» (по убыванию):
?startkey=["fun", "couchdb", {}, {}]&endkey=["fun", "couchdb"]&descending=true
Получите только рейтинги в категория развлечений с тегом couchdb (по возрастанию):
? startkey = ["fun", "couchdb", 0] & endkey = ["fun", "couchdb", 0, {}]
Получать только рейтинги в категория "развлечения" с тегом "couchdb" (по убыванию):
?startkey=["fun", "couchdb", 0, {}]&endkey=["fun", "couchdb", 0]&descending=true
Надеюсь, это поможет. Сложные ключи начинают действительно показывать, насколько эффективны Map / Reduce при нарезке и нарезке данных.
Ура.