MongoDb

MongoDb

SanSYS

Скачать сервер можно отюда

https://www.mongodb.com/download-center/community

Установка не требуется, достаточно запустить

 mongod -port 27011

Или указав точные директорию/порт

 mongod --dbpath ./mongo11 --port 27022

Консоль для подключения - файл mongo[.exe]

Язык запросов в нуль != SQL, рекомендую лайтово глянуть https://docs.mongodb.com/manual/tutorial/query-documents/

Вот пример оттуда

Если не нравится пользоваться терминалом, то есть хороший GUI

https://studio3t.com/download-thank-you/?OS=win64

Что-то похожее на SQL таки есть, но его следует избегать

Книжечка сильно устаревшая))
Следующий код ничего не возвращает

Лучше искать индексы в конкретной коллекции, обычно это и нужно

https://docs.mongodb.com/manual/reference/method/db.collection.getIndexes/

План запроса

Конечно, как и в PG, если есть большая коллекция, то сканить её всю это плохо. А происходит ли это - можно узнать через план запроса. Если в explain ничего не передавать, то план запроса будет только от планнера, см. https://docs.mongodb.com/manual/reference/method/cursor.explain/

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

db.phones.ensureIndex(
  {display: 1},
  {unique: true, dropDups: true}
) 

Метод уже устаревший и является алиасом для https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#db.collection.createIndex

Теперь индекс есть и план выглядит отлично

Конечно же - работает быстро

Значение executionTimeMillis существенно уменьшилось )

Построение индекса по вложенным полям

Пример неблокирующего создания индекса по вложенным полям

Встроенный профилировщик

Не все пользуются explain, потому на тестовых средах можно насильно включать профайлер https://docs.mongodb.com/manual/reference/method/db.setProfilingLevel/index.html

db.setProfilingLevel(2);

После планы запросов будут складироваться в db.system.profile

Агрегированные запросы

Пока всё было замечательно, но group by это полный атас (

Количество доков с components.number > 10000000
Уникальные начения

Но если будет много значений, то словишь ошибку

А вот так выглядит group by с подсчётом количества
Подтверждаю, не этим запросом, но многими ноут я пошатал)

Рекомендую сходить в доку и посмотреть иные примеры метода aggregate

https://docs.mongodb.com/manual/reference/operator/aggregation/group/index.html

Хранимки

https://docs.mongodb.com/manual/reference/system-collections/index.html#%3Cdatabase%3E.system.js

Кластер

Для начала нужно запустить три сервера, с разными портами и директориями (три, пять, семь, классика):

mongod --replSet book --dbpath ./mongo1 --port 27011
mongod --replSet book --dbpath ./mongo2 --port 27012
mongod --replSet book --dbpath ./mongo3 --port 27013

После подключиться к любому:

mongo --port 27011

И выполнить инициалиацию:

 rs.initiate({ 
    _id: 'book', 
    members: [ 
      {_id: 1, host: 'localhost:27011'}, 
      {_id: 2, host: 'localhost:27012'}, 
      {_id: 3, host: 'localhost:27013'} 
    ]
})

Через команду rs.status() дождаться появления первичной ноды

Для проверки - в первичную ноду вставляю новое значение:

book:PRIMARY> db.echo.insert({say: 'Hi there!'})
WriteResult({ "nInserted" : 1 })

И стопаю её )

В логах оставшихся нод наблюдается паника

Но если подключиться ко второй ноде - видно, что она стала первичной и вставленное значение присутсвует

$ mongo --port 27012
book:PRIMARY> db.echo.find()
{ "_id" : ObjectId("5d340ad9cfb70cde3e8b8ab8"), "say" : "Hi there!" }

Если неудобно смотреть JSON через консоль, то можно юзать Robo

Казалось бы - есть рабочие реплики и отлаженный фейловер, но любая работа с не мастер нодами - фейл (и запись, и чтение). Они только для репликации и фейловера

Шардинг

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

Кратко, как настраивается:

  1. запускается несколько узлов в режиме поддержки шардинга (shards)
  2. запускается отдельный узел-конфигурации (config servers)
  3. Запускается отдельный роутер - точка входа для клиентов (Routers)

https://docs.mongodb.com/manual/sharding/


Про опечатки - речь идёт про операцию обновления, т.е. нельзя писать вот так:

db.inventory.updateMany(
  { "qty": { $lt: 50 } },
  { "size.uom": "in", status: "P" }
)

Нужно явно указывать обновляемое подмножество:

db.inventory.updateMany(
  { "qty": { $lt: 50 } },
  {
   $set: { "size.uom": "in", status: "P" }
  }
)

Иначе сервер затрёт весь документ вашим маленьким доком

P.S.: Консолек будет много ;)


Report Page