Как перевести с SQL на NoSQL / MapReduce? - PullRequest
13 голосов
/ 25 июня 2011

У меня есть опыт работы с реляционными базами данных, но недавно он начал баловаться с 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();

1 Ответ

18 голосов
/ 25 июня 2011

Команды 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);
  }
}

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


DELETE FROM products WHERE expires_at <= NOW();

Карта

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

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

...