BSON - формат данных в MongoDB
В MongoDB все иначе. Если какому-то ключу не сопоставлено значение, то этот ключ просто опускается в документе и не употребляется.
Если в традиционном мире SQL есть таблицы, то в мире MongoDB есть коллекции.
Система GridFS состоит из двух коллекций. В первой коллекции, которая называется files, хранятся имена файлов, а также их метаданные, например, размер. А в другой коллекции, которая называется chunks, в виде небольших сегментов хранятся данные файлов, обычно сегментами по 256 кб. Для тестирования GridFS можно использовать специальную утилиту mongofiles, которая идет в пакете mongodb.
Всего имеется следующие типы значений:
- String: строковый тип данных, как в приведенном выше примере (для строк используется кодировка UTF-8)
- Array (массив): тип данных для хранения массивов элементов
- Binary data (двоичные данные): тип для хранения данных в бинарном формате
- Boolean: булевый тип данных, хранящий логические значения TRUE или FALSE, например, {"married": FALSE}
- Date: хранит дату в формате времени Unix
- Double: числовой тип данных для хранения чисел с плавающей точкой
- Integer: используется для хранения целочисленных значений, например, {"age": 29}
- JavaScript: тип данных для хранения кода javascript
- Min key/Max key: используются для сравнения значений с наименьшим/наибольшим элементов BSON
- Null: тип данных для хранения значения Null
- Object: строковый тип данных, как в приведенном выше примере
- ObjectID: тип данных для хранения id документа
- Regular expression: применяется для хранения регулярных выражений
- Symbol: тип данных, идентичный строковому. Используется преимущественно для тех языков, в которых есть специальные символы.
- Timestamp: применяется для хранения времени
Начиная работать с MongoDB, первым делом надо установить нужную нам базу данных в качестве текущей, чтобы затем ее использовать. Для этого надо использовать командуuse
, после которой идет название базы данных. При этом не важно, существует ли такая бд или нет.
show dbs
вывести названия всех баз данных
// добавление одного документа
db.users.insertOne({"name": "Tom", "age": 28, languages: ["english", "spanish"]})
// вывести коллекцию users
db.users.find()
// добавление нескольких документов
db.users.insertMany([{"name": "Bob", "age": 26, languages: ["english", "frensh"]},
{"name": "Alice", "age": 31, languages:["german", "english"]}])
db.users.insert({"name": "Tom", "age": 28, languages: ["english", "spanish"]})
> document=({"name": "Bill", "age": 32, languages: ["english", "french"]})
> db.users.insert(document)
Переименование коллекции
> db.users.renameCollection("новое_название")
{"ok" : 1}
Явное создание коллекции
db.createCollection("accounts")
Подколлекции
Для упрощения организации данных в коллекциях мы можем использовать подколлекции. Например, данные по коллекции users надо разграничить на профили и учетные данные. И мы можем использовать создать коллекции db.users.profiles
иdb.users.accounts
. При этом они не будут никак связаны с коллекциейusers
, то есть в итоге будут три разные коллекции, однако в плане логической организации хранения данных, возможно, для кого-то так будет проще.
Выборка
Для вывода документов в более удобном наглядном представлении мы можем добавить вызов метода pretty()
db.users.find().pretty()
> db.users.find({name: "Tom"}, {age: 1})
Использование единицы в качестве параметра{age: 1}
указывает, что запрос должен вернуть только содержание свойства age. И обратная ситуация: мы хотим найти все поля документа кроме свойства age. В этом случае в качестве параметра указываем 0:
Альтернативно вместо 1 и 0 можно использовать true и false:
> db.users.find({name: "Tom"}, {age: true, _id: false})
Вложенные обьекты
> db.users.insert({"name": "Alex", "age": 28, company: {"name":"microsoft", "country":"USA"}})
> db.users.find({"company.name": "microsoft"})
Использование JavaScript
> fn = function() { return this.name=="Tom"; }
> db.users.find(fn)
// аналогично
> db.users.find("this.name=='Tom'")
Использование регулярных выражений
> db.users.find({name:/T\w+/i})
// первые 3 результата
> db.users.find().limit(3)
// одинаковые запросы
> db.users.find().limit(3)
> db.users.findOne()
// пропустить первые 3 результата
> db.users.find().skip(3)
// сортировка по возрастанию (по убыванию = -1)
> db.users.find().sort({name: 1})
Например, отберем последние пять документов:
> db.users.find().sort({ $natural: -1 }).limit(5)
И мы хотим при выводе документов сделать так, чтобы в выборку попадал только один язык из массива languages, а не весь массив:
> db.users.find ({name:"Tom"}, {languages: {$slice : 1}})
> db.users.find ({name:"Tom"}, {languages: {$slice : -1}}) // последний
Чтобы получить курсор и сразу же не выводить все содержащиеся в нем данные, после метода find() добавляет через точку с запятой выражение null;
> var cursor = db.users.find();null;
> while(cursor.hasNext()){
... obj = cursor.next();
... print(obj["name"]);
... }
> var cursor = db.users.find()
> cursor.forEach(function(obj){
... print(obj.name);
... })
Число элементов. Надо отметить, что по умолчанию функция count не используется с функциями limit и skip. Чтобы их использовать, как в примере выше, в функцию count надо передать булевое значение.true
> db.users.find({name: "Tom"}).skip(2).count(true)
Условные операторы
- $eq (равно)
- $gt (больше чем)
- $lt (меньше чем)
- $gte (больше или равно)
- $lte (меньше или равно)
> db.users.find ({age: {$lt : 30}})
> db.users.find ({age: {$gt : 30, $lt: 50}})
// !22
> db.users.find ({age: {$ne : 22}})
Поиск по массивам и операторы $in, $nin, $all
Оператор $in определяет массив возможных выражений и ищет те ключи, значение которых имеется в массиве:
> db.users.find ({age: {$in : [22, 32]}})
// действует противоположным образом. Все, которые не имеются в массиве
> db.users.find ({age: {$nin : [22, 32]}})
// должны совпадать все значения
> db.users.find ({age: {$all : [22, 32]}})
> db.users.find ({age: {$all : [22]}})
// извлечем все документы, в которых в массиве laguages два элемента:
> db.users.find ({languages: {$size:2}})
// вернем все документы, в который есть ключ company:
> db.users.find ({company: {$exists:true}})
$type извлекает только те документы, в которых определенный ключ имеет значение определенного типа, например, строку или число:
> db.users.find ({age: {$type:"string"}})
> db.users.find ({age: {$type:"number"}})
// Оператор $regex задает регулярное выражение, которому должно соответствовать значение поля. Например, пусть поле name обязательно имеет букву "b":
> db.users.find ({name: {$regex:"b"}})
// Оператор $or представляет логическую операцию ИЛИ
> db.users.find ({$or : [{name: "Tom"}, {age: 22}]})
// Оператор $and представляет логическую операцию И
> db.users.find ({$and : [{name: "Tom"}, {age: 32}]})