Node.JS + MongoDB
Посоветуйте пожалуйста чтиво по этому поводу.
Из основных вопросов: Пока не понял как правильно работать с открытием соединения к базе, хочу использовать модуль mongodb и думаю никакие mongoose не надо. Цель - создать REST API для начала. |
Ответ: Node.JS + MongoDB
Не нужно книжек и чтивы. Если работал с mongo то там всё проактически идентично официальным докам (в случае с mongoose это не так).
Я юзал mongoose и потом перешёл на mongo-native от самих 10gen - и не жалею вовсе. Мне эти schemas - нафиг не сдались. Суть mongo - в её динамике, и нефиг пытаться прикручивать правила и структуру к collection'ам подобно это SQL бд. Офф дока - очень полезна, т.к. как уже говорил почти идентична к mongo-native в использовании. По факту - коммандная строка для mongo тоже на JavaScript'е ;) Про соединение, сперва тебе нужно создать объект куда коннектиться: PHP код:
PHP код:
PHP код:
https://github.com/mongodb/node-mong...aster/examples Есть пару тонкостей:
Если есть конкретные вопросы - задавай. Я пишу по работе RESTful API с mongo-native и express'ом ну и другими всякими плюшками. |
Ответ: Node.JS + MongoDB
Правильно ли я понимаю, что для каждого REST запроса надо создавать свое подключение? Мне сначала подумалось создать одно подключение к базе на старте приложения и потом его использовать. Потом я посмотрел некоторые рест библиотеки для монго и там для каждого запроса создается свой экземпляр Db. Такой подход верный?
Еще один вопрос - есть у nodejs возможность запускаться в многопроцессном режиме, это не стоит использовать для REST API? |
Ответ: Node.JS + MongoDB
Не нужно для каждого запроса свой db хэндлер - это оверкил.
Там блокировка на уровне бд будет а не на уровне node, следственно иметь более одного хэндла - смысла нету, только замедляет процесс. Возможно mongo-native кеширует коннекты и будет выдавать уже подконекченный - но это снова лишние телодвижения. Относительно мультипоточности - ты говоришь о cluster? Мы используем - 4 worker'а. Всё работает как полагается, естественно если у тебя есть сессия, то её нужно хранить вне процесса, мы используем connect-mongo, тем самым не важно в какой worker идёт запрос. По опыту пришёл к такому выводу - если у тебя есть CMS и write'ы очень редкие, и обслуживаются определённой группой людей, следственно таскать с собой функционал для CMS в основном API не оправдано. Для этого я сделал отдельные запросы для PUSH'ей, это немного идёт против логики REST'а, т.к. /url будет отличаться (я сделал субдомейн для этого, а руты были те же), но зато когда нужно обновить основной API, не нужно было перегружать CMS и т.п. Но это зависит от ситуации. cluster'ы - реально помогают, их количество обычно параллельно количеству ядер. Мы на ec2 xlarge (4 CPU) 4 worker'а запускаем - и всё ок. |
Ответ: Node.JS + MongoDB
Еще пара вопросов:
1. Как правильно обрабатывать ошибки, чтобы при их происхождении не падал весь процесс. Можно конкретно для express и mongodb. 2. Я так понимаю что кластер можно использовать как защиту от падения процесса, т.е. кластер при падении одного воркера может запустить нового воркера? И если надо будет перезапустить сервер, то просто необходимо будет перезапустить кластер да? 3. Какой модуль лучше использовать для логирования? Особенно если используется кластер и несколько воркеров. |
Ответ: Node.JS + MongoDB
Цитата:
Важно понимать что ошибки - это важно, и их не должно быть. Если в тестировании ошибок в запросах к бд небыло, а потом есть, значит твой query слишком динамичен и нужно его немного нормализировать (это 90% случаев). Я у себя в коде так делаю: Ранее при настройке express'а: PHP код:
PHP код:
PHP код:
Цитата:
Вообще есть "защито" от падения процесса. Есть event который ловит не словленные exception'ы. Но естественно если что-то жесть как пошло не так, то нужно и реагировать соответственно, а не тупо игнорировать. Но всё равно: PHP код:
Цитата:
Суть у него в том что он имеет основу для логгирования, но логит в транспорты, которые могут быть что угодно: консоль, файл, бд, MQ, redis, socket, amazon alerts, email, и т.п. Есть стандартный набор транспортов которых обычно хватает с головой. Я лично юзать буду файл + бд (с индексом просрочивания неделю), и ZeroMQ в мелкий процесс который через socket.io будет слать логи от разных процессов мне на мелкую страничку мониторинга. Таким образом если что-то случиться, я сразу могу вычислить с кем, где и т.п. |
Ответ: Node.JS + MongoDB
Хочу часть логики сделать на хранимом js в MongoDB, это лучше чем делать логику в NodeJS?
Upd: кстати как правильно вызывать хранимые функции? Upd2: Получилось примерно так: PHP код:
Это нормально или я что-то не так делаю? |
Ответ: Node.JS + MongoDB
Я предпочитаю ничего не хранить в DB. Можно лишь мелкие туулзы или функции утилит, но не относящиеся к логике твоего приложения - это ответственность твоего API.
Да и сразу по твоей функции - ты доверяешь назначение user_id кому? БД, или логике приложения? Я пытался сделать подобное - вставлять если нету, но потом пришёл к выводу - нефиг! Есть куча сценариев где тебе нужно получить юзверя - но он может и не быть там, следственно и вставлять его не нужно. Так что лучше разделить эту логику. Да и если ты 100% вставляешь, то не используй 'save', а используй 'insert'. save - весьма опасен, тем что если будешь обновлять что-то (ожидая update), а документа такого не будет, а обновление будет partial (только пару полей), то вставиться "не полный" документ, что твоя логика приложения не будет ожидать. И мелкая заметка, в node, для даты проще писать так: Date.now() - получает timestamp. |
Ответ: Node.JS + MongoDB
У меня это авторегистрация такая. id это id пользователя в соц сети. На счет insert спасибо, буду иметь ввиду. И я уже решил делать логику в ноде, а не в БД, а то получается какая-то фигня (не нравится мне такой код) с вызовами.
|
Ответ: Node.JS + MongoDB
Я тут щас aggregation и mapReduce изучаю. Заодно открыл для себя $where.
$where - позволяет стрингой передать сроку кода, например: Пример player'а: PHP код:
PHP код:
PHP код:
Следственно например для collection'а с 2800 записями, у меня затрачивается 72мс (на простом Mac'е), что ужасно долго для таких запросов. Следственно в реальном мире лучше кешировать длину массива рядом с массивом. Но всё же, если у тебя например запрос на 32 записи (например), то такой код - вполне приемлем. Нужно исследовать как там с блоком всего процесса (блокирует ли другие запросы и т.п.). aggregation - это интерестный монстрик, по получению всяких данные и более сложных манипуляций над документами. Например у меня есть записи игроков, и у каждого игрока есть любимая команда. Мне нужно получить список всех команд и сколько игроков её указали как любимую: PHP код:
Всего там 20 команд. В результате получу массив с до 20 записями такого вида: PHP код:
mapReduce - это ещё следующий шаг. Когда aggregation предоставляет операторы, и там важна их поочерёдность и т.п., то mapReduce принимает лишь 2 функции и query фильтр. Первая функция обрабатывает каждый документ (удовлетворяющий query) и если нужно вызывает emit, что передаёт уже обработанные данные (можно и не обработанные) в reduce функцию, где уже дальше мы имеем дело с групированными данными. Примеров много можно привезти, в моём случае, нужно было узнать сколько призов в среднем выйграл каждый игрок. Есть 2800 записей. И нужно получить общее арифметическое колличества призов: PHP код:
Снова, для тысячей записей - это не шустро, но для статистики - самое то. |
Ответ: Node.JS + MongoDB
Заметил что таймштамп в ноде в миллисекундах, а не в секундах как это в php. Поделил все на 1000)
|
Ответ: Node.JS + MongoDB
Цитата:
Тем более что если захочешь перевезти timestamp в дату то: PHP код:
|
Ответ: Node.JS + MongoDB
Бенефит: в базе либо Int32 если секунды, либо double если миллисекунды.
PS: начинаю втягиваться, на первый взгляд сложнее чем на php, потому что надо писать асинхронный код, с другой стороны вроде как и интереснее получается. |
Ответ: Node.JS + MongoDB
Цитата:
http://stackoverflow.com/questions/6...tes-in-mongodb Цитата:
Правда появяться некоторые "трудности", например запустить сразу 3 асинхронных функции, и потом финальную функцию, или сделать очередь асинхронных функций. Есть promise и async.js, но я как обычно юзаю свой вариант решения простой задачи: PHP код:
Вторая запускает все асинхронно и финальную когда все закончили. Пользоваться так: PHP код:
PHP код:
Как видишь он даже не начинает выполнение следующей функции до выполнения прошлой. PHP код:
И тут видно что он запускает все сразу, но финальную только когда каждая функция запустит next() по завершению (асинхронно или нет). |
Ответ: Node.JS + MongoDB
В тему асинхронного кода, юмор:
var result = fs.readFile(‘data.json’, function () {}) |
Часовой пояс GMT +4, время: 11:42. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot