Подтвердить что ты не робот

Как перевести с SQL на NoSQL/MapReduce?

У меня есть фон, работающий с реляционными базами данных, но в последнее время он начал разбираться в CouchDB и был удивлен тем, как некоторые нереляционные операции, которые были бы простыми в SQL, не были первоклассными функциями в CouchDB.

Я был бы признателен, если вы потратили немного времени, чтобы сопоставить каждый оператор SQL ниже с его эквивалентом MapReduce.

SELECT COUNT(*) FROM products WHERE price < 20.00;
SELECT category, SUM(price) FROM products GROUP BY category;
UPDATE products SET price = 19.99 WHERE price = 20.00;
DELETE FROM products WHERE expires_at <= NOW();
4b9b3361

Ответ 1

Команды SELECT довольно просты. Массовые записи немного сложнее. Как правило, вы будете использовать некоторое представление для получения документов, которые необходимо изменить, тогда вы будете использовать API _bulk_docs для отправки всех изменения сразу.

Кроме того, обратитесь к документации относительно представлений для получения подробной информации о том, как выпускать запросы. Это включает упорядочение, группировку и т.д.


SELECT COUNT(*) FROM products WHERE price < 20.00;

Карта

function (doc) {
  if (doc.price < 20) {
    emit(doc.price);
  }
}

Снизить

_count

Если вам нужно работать с произвольной суммой, а не только с 20, вам нужно будет исправить цену во всех случаях и использовать startkey и endkey, чтобы сузить набор результатов.


SELECT category, SUM(price) FROM products GROUP BY category;

Карта

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

Снизить

_sum

Эта функция карты по существу использует категорию как ключ, а цена - как значение в вашей паре ключ/значение. Функция уменьшения добавит цены для каждого другого ключа.


UPDATE products SET price = 19.99 WHERE price = 20.00;

Карта

function (doc) {
  if (doc.price == 20) {
    emit(doc.price);
  }
}

Как только ваше приложение вытащит содержимое этого представления, вы выполните все действия в коде приложения, а затем отправьте результаты в базу данных с помощью API _bulk_docs.


DELETE FROM products WHERE expires_at <= NOW();

Карта

function (doc) {
  emit(doc.expires_at);
}

В зависимости от того, как хранятся ваши значения даты и времени, вам может потребоваться настроить функцию карты, а также ваш запрос к представлению. Использование метки времени (JS использует миллисекунды вместо секунд), вероятно, самый быстрый способ выполнить это. После того как вы настроили свой запрос, вы добавите новое поле в каждый из этих документов. _deleted: true. После отправки этого списка в базу данных (снова с помощью _bulk_docs) все указанные документы будут удалены.