Рубрики
Без рубрики

NEDB: легкая база данных JavaScript

Автор оригинала: Scott Robinson.

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

Рассмотрим настольное приложение чата, написанное с Электрон Рамки в JavaScript. В то время как данные чата (сообщения, контакты, история и т. Д.), вероятно, будут возникнуть с API-сервера, ему также необходимо хранить локально внутри приложения. Вы можете потенциально иметь тысячи сообщений, все из которых нужно было бы хранить для легкого доступа и поиска.

Ну так что ты делаешь? Один вариант – хранить все эти данные в файл где-то и просто искать его каждый раз, когда вам нужно получить его, но это может быть неэффективным. Другой вариант – просто не кэшировать данные локально и сделать вызов API Siver каждый раз, когда вам нужно больше данных, но тогда ваше приложение будет менее отзывчивым и будет использовать гораздо больше сетевых данных.

Лучшая идея состоит в том, чтобы использовать встроенную/легкую базу данных, например Недб Отказ Это имеет больше смысла, потому что ваше приложение не будет обслуживать тысячи пользователей или обработки гигабайт данных.

NEDB много как SQLite В этом это меньшая, встраиваемая версия гораздо большей системы базы данных. Вместо того, чтобы быть меньшим хранением SQL DataStore, NEDB – это меньший хранилище NoSQL, который имитирует Монгодб Отказ

Легкая база данных обычно хранит свои данные в памяти, либо в простом текстовом файле (с индексами для быстрого поиска). Это помогает уменьшить общий след базы данных в системе, которая идеально подходит для более мелких приложений. Для сравнения файл MySQL TAR (для Mac OSX) составляет 337 МБ, в то время как NEDB (несжатый, не был полезным) составляет всего около 1,5 МБ.

Одна из самых больших вещей о NEDB в частности, в том, что его API является подмножеством API MongoDB, поэтому, если вы знакомы с Mongodb, у вас не должно быть проблем с работы с NEDB после начальной настройки.

Примечание : Поскольку V1.8.0 NEDB еще не обновляется до новых имен Mongo, таких как Вставить , insermany и удаление Findone Отказ

Начало работы с NEDB

Сначала установите модуль с NPM:

$ npm install nedb --save

Модуль написан в чистом JavaScript, поэтому не должно быть никаких проблем, составивших нативных дополнений, таких как иногда есть драйверы MongoDB.

Если вы планируете использовать его в браузере вместо этого, используйте Bower для установки:

$ bower install nedb

Как и все клиенты базы данных, первый шаг должен подключиться к базе данных Backend. Однако в этом случае нет внешнего приложения для подключения к подключению, поэтому вместо этого нам просто нужно сказать ему местоположение ваших данных. С NEDB у вас есть несколько вариантов сохранения ваших данных. Первый вариант – сохранить данные в памяти:

var Datastore = require('nedb');
var db = new Datastore();

// Start issuing commands right away...

Это начнет вас без данных, и когда вы бронируете приложение, все сохраненные данные будут потеряны. Хотя это здорово для использования во время тестирования или более коротких сеансов (например, в браузере).

Или другой вариант – сохранить данные в файл. Разница здесь заключается в том, что вам нужно указать местоположение файла и загрузить данные.

var Datastore = require('nedb');
var db = new Datastore({ filename: 'path/to/your/file' });

db.loadDatabase(function(err) {
    // Start issuing commands after callback...
});

Если вы не хотите звонить db.loaddatabase Для каждой базы данных вы загружаете, вы всегда можете использовать Autoload: True опция тоже.

Одно важное замечание в том, что каждый файл является эквивалентом одного Коллекция в монгодб. Поэтому, если у вас есть несколько коллекций, вам нужно загрузить несколько файлов на запуск. Таким образом, ваш код может выглядеть так:

var Datastore = require('nedb');
var users = new Datastore({ filename: 'users.db', autoload: true });
var tweets = new Datastore({ filename: 'tweets.db', autoload: true });
var messages = new Datastore({ filename: 'messages.db', autoload: true });

Сохранение данных

После загрузки ваших данных из файлов (или создание хранения в памяти) вы захотите начать сохранение данных.

Многое, как драйверы Mongo, вы будете использовать Вставить Создать новый документ:

var Datastore = require('nedb');
var users = new Datastore();

var scott = {
    name: 'Scott',
    twitter: '@ScottWRobinson'
};

users.insert(scott, function(err, doc) {
    console.log('Inserted', doc.name, 'with ID', doc._id);
});

// Prints to console...
// (Note that ID will likely be different each time)
//
// "Inserted Scott with ID wt3Nb47axiOpme9u"

Эта вставка может быть легко расширена, чтобы сохранить несколько документов одновременно. Используя тот же метод, просто пропустите массив объектов, и каждый будет сохранен и возвращен вам в обратном вызове:

var Datastore = require('nedb');
var users = new Datastore();

var people = [];

var scott = {
    name: 'Scott Robinson',
    age: 28,
    twitter: '@ScottWRobinson'
};

var elon = {
    name: 'Elon Musk',
    age: 44,
    twitter: '@elonmusk'
};

var jack = {
    name: 'Jack Dorsey',
    age: 39,
    twitter: '@jack'
};

people.push(scott, elon, jack);

users.insert(people, function(err, docs) {
    docs.forEach(function(d) {
        console.log('Saved user:', d.name);
    });
});

// Prints to console...
//
// Saved user: Scott Robinson
// Saved user: Elon Musk
// Saved user: Jack Dorsey

Обновление существующих документов работает намного одинаково, за исключением того, что вам нужно будет предоставить запросу, чтобы сообщить системе, которую необходимо обновить документ (ы).

Загрузка данных

Теперь, когда у нас есть куча данных сохранена, пришло время получить его обратно из базы данных. Опять же, мы будем следовать той же конвенции, что и Монго с Найти Метод:

var Datastore = require('nedb');
var users = new Datastore();

// Save a bunch of user data here...

users.findOne({ twitter: '@ScottWRobinson' }, function(err, doc) {
    console.log('Found user:', doc.name);
});

// Prints to console...
//
// Found user: Scott Robinson

И снова мы можем использовать аналогичную операцию для извлечения нескольких документов. Возвращенные данные – это просто массив соответствующих документов:

var Datastore = require('nedb');
var users = new Datastore();

// Save a bunch of user data here...

users.find({ age: { $lt: 40 }}, function(err, docs) {
    docs.forEach(function(d) {
        console.log('Found user:', d.name);
    });
});

// Prints to console...
//
// Found user: Jack Dorsey
// Found user: Scott Robinson

Вы могли бы заметить из этого последнего примера кода, что NEDB, как ожидаю, способен к более сложным запросам, как сравнение номеров. Следующие операторы доступны для поиска/сопоставления документов:

  • $ LT , $ LTE : меньше, меньше, меньше или равно
  • $ GT , $ GTE : больше, чем больше или равна
  • $ в : значение, содержащееся в массиве
  • $ NIN : значение, не содержащееся в массиве
  • $ ne : не равный
  • $ существует : проверяет существование (или не существование) данного свойства
  • $ Regex : Сопоставьте строку свойства с Regex

Вы также можете использовать стандартную сортировку, ограничение и пропускные операции. Если обратный вызов не дан Найти Метод, то A Курсор Объект будет возвращен вам вместо этого, который вы можете использовать для сортировки, ограничения и пропускания. Вот пример сортировки в алфавитном порядке по имени:

var Datastore = require('nedb');
var users = new Datastore();

// Save a bunch of user data here...

users.find({}).sort({name: 1}).exec(function(err, docs) {
    docs.forEach(function(d) {
        console.log('Found user:', d.name);
    });
});

// Prints to console...
//
// Found user: Elon Musk
// Found user: Jack Dorsey
// Found user: Scott Robinson

Два других операции, пропустить и ограничить, работают очень похожи на это.

Есть еще несколько операторов, поддерживаемых Найти и Findone Методы, но мы не будем войти ко всему здесь. Вы можете подробно прочитать о остальных этих операциях в Поиск документов Раздел Readme.

Удаление данных

Нельзя сказать о удалении данных, отличных от того, что она работает похожи на Найти методы. Вы будете использовать те же типы запросов, чтобы найти соответствующие документы в базе данных. Те, которые найдены, затем удаляются.

var Datastore = require('nedb');
var users = new Datastore();

// Save a bunch of user data here...

users.remove({ name: { $regex: /^Scott/ } }, function(err, numDeleted) {
     console.log('Deleted', numDeleted, 'user(s)');
});

// Prints to console...
//
// Deleted 1 user(s)

По умолчанию Удалить Способ удаляет только один документ. Для того, чтобы удалить несколько документов одним вызовом, вы должны установить мульти Вариант для правда Отказ

var Datastore = require('nedb');
var users = new Datastore();

// Save a bunch of user data here...

users.remove({}, { multi: true }, function(err, numDeleted) {
     console.log('Deleted', numDeleted, 'user(s)');
});

// Prints to console...
//
// Deleted 3 user(s)

Индексирование данных

Как и любая другая база данных, вы можете установить индексы на ваши данные для более быстрого поиска или для обеспечения применения определенных ограничений, таких как уникальные значения. Чтобы создать индекс, используйте ОБЕСПЕЧЕНИЕМИНГЕКС метод.

Три типа индексов в данный момент поддерживаются:

  • Уникальный : Убедитесь, что данное поле уникально на протяжении всей коллекции
  • Редкий : не указатель документов, в которых данное поле не определено
  • EXPIREAEPTERSECONDS : Удалите документ после данного количества секунд ( Время для жизни или TTL)

Индекс TTL особенно полезен, на мой взгляд, поскольку он сохраняет вас от необходимости записи кода, чтобы часто сканировать и удалить истекшие срок действия данных.

Это может быть полезно, например, с запросами сброса пароля. Если у вас есть PasswordReset Объект, хранящийся в вашей базе данных, вы не хотите, чтобы это было действительно навсегда. Чтобы помочь защитить пользователя, он, вероятно, должен истереть и быть удален через несколько дней. Этот индекс TTL может обрабатывать удаление для вас.

В следующем примере мы разместили Уникальный Ограничение на ручках Twitter документов. Это означает, что если пользователь сохраняется с одной и той же рукояткой Twitter, что и другой пользователь, будет брошена ошибка.

var Datastore = require('nedb');
var users = new Datastore();

users.ensureIndex({ fieldName: 'twitter', unique: true });

var people = [];

var jack = {
    name: 'Jack Dorsey',
    age: 39,
    twitter: '@jack'
};

var jackSmith = {
    name: 'Jack Smith',
    age: 68,
    twitter: '@jack'
};

people.push(jack, jackSmith);

users.insert(people, function(err, docs) {
    console.log('Uh oh...', err);
});

// Prints to console...
//
// Uh oh... Can't insert key @jack, it violates the unique constraint

Принимать его дальше

В то время как API NEDB прост в использовании и все, ваш код может стать довольно сложно работать, если он не очень хорошо продуман и организован. Это где объектные документы Mappers ( это похоже на ORM ).

Используя CAMO ODM (который я создал), вы можете просто лечить DEDB Datastores в виде классов JavaScript. Это позволяет указывать схему, проверку данных, расширять схемы и многое другое. CAMO даже работает с MongoDB, поэтому вы можете использовать NEDB в средах тестирования/разработки, а затем использовать Mongo для вашей производственной системы без необходимости менять какой-либо из вашего кода.

Вот быстрый пример подключения к базе данных, объявляя объект класса и сохранение некоторых данных:

var connect = require('camo').connect;
var Document = require('camo').Document;

class User extends Document {
    constructor() {
        super();

        this.name = String;
        this.age = Number;
        this.twitter = Sring;
    }

    get firstName() {
        return this.name.split(' ')[0];
    }
}

var scott = User.create({
    name: 'Scott Robinson',
    age: 28,
    twitter: '@ScottWRobinson'
});

var elon = User.create({
    name: 'Elon Musk',
    age: 44,
    twitter: '@elonmusk'
});

connect('nedb://memory').then(function(db) {
    return Promise.all([scott.save(), elon.save()]);
}).then(function(users) {
    users.forEach(function(u) {
        console.log('Saved user:', u.firstName);
    });

    return elon.delete();
}).then(function() {
    console.log('Deleted Elon!')
});

// Prints to console...
//
// Saved user: Scott
// Saved user: Elon
// Deleted Elon!

Для этого ODM намного больше, чем то, что я показал здесь. Для получения дополнительной информации проверить Эта статья или Проект Readme для документации.

Заключение

С NEDB быть довольно маленьким (и довольно быстро!), Очень легко добавить его к любому проекту. А с камуфляцией в смеси вам нужны несколько строк кода, только для объявления объектов на основе классов, которые намного легче создавать, удалять и манипулировать.

Если вы когда-либо использовали NEDB в одном из ваших проектов, мы хотели бы услышать об этом. Дайте нам знать об этом в комментариях!