Сортировка CouchDB и просачивание того же представления

Я пытаюсь использовать 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". Я хочу отсортировать те фильтрованные результаты путем рейтинга в порядке убывания, затем по дате в порядке возрастания, затем заголовком в алфавитном порядке.

Как я могу создать одно представление, которое делает всю ту сортировку и объединенную фильтрацию?

33
задан Apreche 22 July 2010 в 16:46
поделиться

1 ответ

Чтобы передать более одного фрагмента данных в ключе, прочтите статью Комплексные ключи . Скорее всего, вы получите 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 при нарезке и нарезке данных.

Ура.

49
ответ дан 27 November 2019 в 18:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: