Библиотека для новых пользователей

Примечание редактора:. В феврале 2018 г. библиотека silverlining устарела и заменена на cloudant-quickstart: https://www.npmjs.com/package/cloudant-quickstart

Я часто разговариваю с разработчиками, которые впервые используют IBM Cloudant или Apache CouchDB ™, и обнаружил, что им чаще всего сложно принять следующие концепции:

  • Проектная документация: особенность, уникальная для этого семейства баз данных. Это специальные документы JSON, содержащие определения индексов и другую магию манипулирования данными. После освоения проектная документация может быть использована с большим эффектом, но для новичка она сбивает с толку.
  • Контроль одновременного выполнения нескольких версий: MVCC - это механизм, с помощью которого документы хранятся в виде дерева ревизий, что позволяет базам данных синхронизировать изменения с другими копиями без потери данных.

Обычно разработчики хотят изучить механику СУБД CRUD и базовые запросы. Они не хотят узнавать о проектных документах, чтобы запрашивать или агрегировать данные, а также не хотят, чтобы MVCC мешал хранению и обновлению их данных. Как бы Cloudant или CouchDB выглядели без этих концепций? Или без функций отображения и списка, обработчиков обновлений, вложений, репликации и других дополнительных функций?

Чтобы выяснить это, я написал библиотеку silverlining, которая скрывает эту мощную, но эзотерическую функциональность и концентрируется на том, чтобы сделать манипулирование данными простым и интуитивно понятным.

Представляем silverlining

Библиотека silverlining - это модуль Node.js, который можно использовать с Cloudant и который позволяет:

  • создание базы данных
  • вставка документа, обновление, массовая вставка и удаление
  • получение документов, множественное получение и массовая выборка
  • запрос к базе данных
  • агрегирование для подсчета, суммирования и статистики

Все это достигается без того, чтобы пользователи сталкивались с какими-либо внутренними сложностями Cloudant.

Установка

Используйте библиотеку в собственном проекте следующим образом:

> npm install --save silverlining

Затем используйте его в своем коде, добавив URL-адрес своего экземпляра Cloudant и определив, с какой базой данных Cloudant вы хотите работать:

var url = 'https://myusername:[email protected]';
var cities = require('silverlining')(url, 'cities');

Создание базы данных

Новую базу данных Cloudant можно создать при первом использовании с помощью функции create:

cities.create();

Все вызовы функций, которые мы здесь делаем, будут асинхронными: они возвращают обещание, которое вы обрабатываете с помощью функций then и catch, но для краткости я опустил большую часть этого каркаса в примерах кода. Например, чтобы зарегистрировать вывод функции info, вы можете сделать:

cities.info().then(console.log)

Теперь мы собираемся импортировать некоторые данные с geonames.org, который хранит местоположение и население городов по всему миру.

Вставка данных

Отдельные документы могут быть добавлены в базу данных с помощью функции insert:

var city = { 
  _id: '3041563', 
  name:'Andorra la Vella', 
  latitude: 42.50779, 
  longitude: 1.52109, 
  country: 'AD', 
  population: 15853, 
  timezone: 'Europe/Andorra' 
};
cities.insert(city);

Если указано свойство _id, это поле становится ключевым полем документа JSON, хранящегося в Cloudant. Если не указано, база данных автоматически генерирует _id.

Эту же функцию можно использовать для вставки нескольких документов - вместо этого просто передайте массив объектов:

var multi = [
  {
    _id: '1000501',
    name: 'Grahamstown',
    latitude: -33.30422,
    longitude: 26.53276,
    country: 'ZA',
    population: 91548,
    timezone: 'Africa/Johannesburg'
  },
  {
    _id: '1000543',
    name: 'Graaff-Reinet',
    latitude: -32.25215,
    longitude: 24.53075,
    country: 'ZA',
    population: 62896,
    timezone: 'Africa/Johannesburg'
  }
];
cities.insert(multi);

Массив данных может быть сколь угодно длинным. Давайте возьмем данные из Github и сохраним их в локальном файле:

curl https://raw.githubusercontent.com/glynnbird/cities/master/cities.json > cities.json

Затем его можно импортировать партиями с помощью одного вызова функции:

var mydata = require('./cities.json');
cities.insert(mydata);

Записи могут быть получены по их идентификаторам с помощью функции get отдельно:

cities.get('1000543');

Или get записей партиями, предоставив массив идентификаторов:

cities.get(['1000501', '1000543']);

Отдельные записи могут быть обновлены путем предоставления идентификатора и нового тела документа функции update (или просто новому объекту):

cities.update('1000501', newdoc);

Документ можно удалить с помощью функции del:

cities.del('1000501');

Предполагая, что нам удалось создать подходящий набор данных, затем нам нужно запросить его.

Запрос данных

База данных может быть запрошена из любого поля с помощью функции query, передав объект запроса:

cities.query({ name: 'York' }).then(console.log);
[ { _id: '2633352',
    name: 'York',
    latitude: 53.95763,
    longitude: -1.08271,
    country: 'GB',
    population: 144202,
    timezone: 'Europe/London' },
  { _id: '4562407',
    name: 'York',
    latitude: 39.9626,
    longitude: -76.72774,
    country: 'US',
    population: 43718,
    timezone: 'America/New_York' } ]

Запрос может также содержать Операторы селектора Cloudant Query:

// find cities with a population > 5m
cities.query({ population: { '$gt': 5000000} })
// cities with population > 5m in Brazil or USA
cities.query({ population: { '$gt': 5000000}, country: { '$in': ['BR','US']} })

Агрегирование

Создавайте агрегированные представления ваших данных с помощью функций count, sum и stats.

Функция count просто считает вещи:

cities.count().then(console.log)
23515

Он также может подсчитывать вещи, сгруппированные по другим полям в документе:

// get counts of cities by country code
cities.count('country').then(console.log);
{ AD: 2,
  AE: 13,
  AF: 48,
  AG: 1,
  AI: 1,...

Функция sum вычисляет итоги:

// get sum of all population fields
cities.sum('population').then(console.log);
2694222973

Вы также можете использовать sum для группировки итогов по другим полям:

// get totals of population grouped by country
cities.sum('population','country').then(console.log);
{ AD: 36283,
  AE: 3272938,
  AF: 6308267,
  AG: 24226,...

Функция stats вычисляет статистику по одному или нескольким полям, которые можно сгруппировать по другим полям:

// get stats on cities' population by timezone
cities.stats('population', 'timezone').then(console.log);
{ 'Africa/Abidjan': 
   { sum: 8399817,
     count: 57,
     min: 15068,
     max: 3677115,
     mean: 147365.2105263158,
     variance: 240877692698.44693,
     stddev: 490792.9224208993 },
  'Africa/Accra': 
   { sum: 7064394,
     count: 58,
     min: 18077,
     max: 1963264,
     mean: 121799.89655172414,
     variance: 96426027195.8169,
     stddev: 310525.4050731065 },...

Как это работает?

Это все еще Cloudant под капотом, но эта библиотека позаботится о некоторых деталях от вашего имени:

  • При создании базы данных создается индекс Cloudant Query, который индексирует все поля. Затем этот индекс приводит в действие оператор query.
  • Функции update и delete скрывают от вас токены ревизий - за кулисами эти операции извлекают последнюю ревизию, перезаписывая данные предоставленным вами документом. Если сначала это не удается, она пытается повторить попытку позже, до трех раз, с более длительными интервалами времени.
  • Функции count, sum и stats используют встроенный механизм MapReduce Cloudant, при необходимости создавая необходимый проектный документ.

В производственных системах важно понимать проектную документацию, MVCC и другие функции Cloudant, но когда вы только начинаете, полезно иметь возможность быстро записывать данные и создавать запросы без каких-либо проблем.

Это бесплатно?

Да! Это бесплатная библиотека с открытым исходным кодом, которая может работать с любой учетной записью Cloudant.

Не стесняйтесь, и мы будем рады любым отзывам на странице проекта Проблемы GitHub.