Подключение базы данных MongoDB для NodeJS к express

Node.js и MongoDB

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

Последнее обновление: 13.05.2018

Наиболее популярной системой управления базами данных для Node.js на данный момент является MongoDB. Для работы с этой платформой прежде всего необходимо установить сам сервер MongoDB. Подробнее как это сделать, описывается здесь. Кроме самого сервера Mongo для взаимодействия с Node.js нам необходим драйвер.

При подключении и взаимодействии с бд в MongoDB можно выделить следующие этапы:

  1. Подключение к серверу

  2. Получение объекта базы данных на сервере

  3. Получение объекта коллекции в базе данных

  4. Взаимодействие с коллекцией (добавление, удаление, получение, изменение данных)

Итак, создадим новый проект. Для этого определим новый каталог, который будет называться mongoapp. Далее определим в этом каталоге новый файл package.json:

{ «name»: «mongoapp», «version»: «1.0.0», «dependencies»: { «express»: «^4.16.0», «body-parser»: «^1.18.0», «mongodb»: «^3.0.0» } }

В данном случае последняя зависимость — «mongodb» как раз и представляет драйвер. Всю необходимую справочную информацию конкретно по данному драйверу можно найти на https://mongodb.github.io/node-mongodb-native/.

Далее перейдем к этому каталогу в командной строке/терминале и для добавления всех нужных пакетов выполним команду:

Подключение к базе данных

Ключевым классом для работы с MongoDB является класс MongoClient, и через него будет идти все взаимодействия с хранилищем данных. Соответственно вначале мы должны получить MongoClient:

var MongoClient = require(«mongodb»).MongoClient;

Для подключения к серверу mongodb применяется метод connect():

const mongoClient = require(«mongodb»).MongoClient; mongoClient.connect(«mongodb://localhost:27017/», function(err, client){ if(err){ return console.log(err); } // взаимодействие с базой данных client.close(); });

Метод connect принимает два параметра:

  • Адрес сервера. В качестве протокола адреса устанавливается «mongodb://». На локальной машине адресом будет localhost, после которого указывается номер порта. По умолчанию номер порта 27017.

  • Второй параметр представляет функцию обратного вызова, которая срабатывает при установке подключения. Это функция принимает два параметра: err (возникшая ошибка при установке соединения) и client (ссылка на подключенный к серверу клиент).

    Если при подключении возникли ошибки, то мы можем использовать значение err для получения ошибки.

    Если же ошибки нет, то мы можем взаимодействовать с сервером через объект client.

В конце завершения работы с бд нам надо закрыть соединение с помощью метода client.close().

База данных, коллекции и документы

Получив объект подлюченного клиента, мы можем обращаться к базе данных на сервере. Для этого используется метод

client.db(«название_бд»);

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

База данных в MongoDB не имеет таблиц. Вместо этого все данные попадают в коллекции. И в рамках node.js для взаимодействия с базой данных (добавления, удаления, чтения данных) нам потребуется получить объект коллекции. Для этого применяется метод db.collection(«название_коллекции»), в который передается название коллекции.

В отличие от таблиц в реляционных системах, где все данные хранятся в виде строк, в коллекциях в MongoDB данные хранятся в виде документов. Например, добавим в базу данных один документ.

Для этого определим в каталоге проекта следующий файл app.js:

const mongoClient = require(«mongodb»).MongoClient; const url = «mongodb://localhost:27017/»; mongoClient.connect(url, function(err, client){ const db = client.db(«usersdb»); const collection = db.collection(«users»); let user = {name: «Tom», age: 23}; collection.insertOne(user, function(err, result){ if(err){ return console.log(err); } console.log(result.ops); client.close(); }); });

В качестве базы данных здесь используется «usersdb». При этом не важно, что по умолчанию на сервере MongoDB нет подобной базы данных. При первом к ней обращении сервер автоматически ее создаст.

После подключения мы обращаемся к коллекции «users»:

const collection = db.collection(«users»);

Опять же неважно, что такой коллекции по умолчанию нет в бд usersdb, она также будет создана при первом обращении.

Получив коллекцию, мы можем использовать ее методы. В данном случае для добавления одного документа — объекта user применяется метод insertOne(). Этот метод имеет два параметра — сам добавляемый объект и функцию обратного вызова, которая выполняется после добавления.

В этой функции применяются два параметра: err (ошибка, которая может возникнуть при операции) и result (результат операции — добавленный объект).

В функции обратного вызова инспектируется добавленный объект с помощью свойства result.ops. Причем это уже не просто объект user, а объект, который получен обратно из базы данных и который содержит идентификатор, установленный при добавлении.

Теперь перейдем на жестком диске к каталогу, в который установлена mongodb, а в этом каталоге перейдем к папке bin:

Запустим сервер mongodb, который находится в этом каталоге и который представляет собой консольную программу mongod.

Затем запустим наш файл app.js:

Как мы видим, кроме начальных свойств здесь документ еще имеет дополнительное свойство _id — это уникальный идентификатор документа, который присваивается сервером при добавлении.

НазадСодержаниеВперед

Express

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

Последнее обновление: 07.01.2017

В этой главе мы рассмотрим создание сервера с помощью фреймворка Express. Казалось бы, зачем нам нужен дополнительный фреймворк, если мы можем воспользоваться готовым модулем http, который есть в Node.js API. Однако Express сам использует модуль http, но вместе с тем предоставляет ряд готовых абстракций, которые упрощают создание сервера и серверной логики, в частности, обработка отправленных форм, работа с куками, CORS и т.д.

Создадим для проекта новый каталог, который назовем, к примеру, expressapp.

Для хранения информации обо всех зависимостях проекта определим в этом каталоге новый файл package.json:

{ «name»: «expressapp», «version»: «1.0.0» }

Далее перейдем к этому каталогу в командной строке/терминале и для добавления всех нужных пакетов выполним команду:

npm install express —save

Создадим в каталоге проекта новый файл app.js:

// подключение express var express = require(«express»); // создаем объект приложения var app = express(); // определяем обработчик для маршрута «/» app.get(«/», function(request, response){ // отправляем ответ response.send(«<h2>Привет Express!</h2>»); }); // начинаем прослушивать подключения на 3000 порту app.listen(3000);

Для использования Express в начале надо создать объект, который будет представлять приложение:

var app = express();

Для обработки запросов в Express определено ряд встроенных функций, и одной из таких является функция app.get().

Она обрабатывает GET-запросы протокола HTTP и позволяет связать маршруты с определенными обработчиками. Для этого первым параметром передается маршрут, а вторым — обработчик, который будет вызываться, если запрос к серверу соответствует данному маршруту:

app.get(«/», function(request, response){ // отправляем ответ response.send(«<h2>Привет Express!</h2>»); });

Маршрут «/» представляет корневой маршрут.

Для запуска сервера вызывается метод , в который передается номер порта.

Запустим проект и обратимся в браузере по адресу http://localhost:3000/:

И что важно, Express опирается на систем маршрутов, поэтому все другие запросы, которые не соответствуют корневому маршруту «/», не будут обрабатываться:

Теперь изменим файл app.js:

var express = require(«express»); var app = express(); app.get(«/», function(request, response){ response.send(«<h1>Главная страница</h1>»); }); app.get(«/about», function(request, response){ response.send(«<h1>О сайте</h1>»); }); app.get(«/contact», function(request, response){ response.send(«<h1>Контакты</h1>»); }); app.listen(3000);

Теперь в приложении определено три маршрута, которые будут обрабатываться сервером:

НазадСодержаниеВперед

  • 1. на сервере установить nodejs (0.12), mongodb, forever js (npm install forever, после установки nodejs)

  • 2. www – рабочая директория вебсервера (т.е. сюда смотрит Apache)

  • 3. nodejs – содержит бота

  • 4. в www/steamauth/settings.php на строках 1 и 2 вставить ваш домен и api key (генерированный из под аккаунта, на котором будет бот)

  • 5. в www/script.js, на 14 строке заменить csgo-easy.ru на ваш домен

  • 6.

    в www/index.php, через поиск найти "<<<STEAM TRADE OFFER LINK>>>" (без кавычек) и заменить на трейд-оффер линк бота

  • 7. можно попробовать запустить в браузере, вы должны увидеть страничку, но пока еще ничего не работает

  • 8. в nodejs/steambot.config.js вставить apikey (идентичный тому, что в settings.php), логин/пароль

  • 9. убедиться, что права на папку nodejs на сервере позволят ему записать файл в эту папку

  • 10. запускаем nodes приложение (cd path/to/your/folder/nodejs; node steambot.js)

  • 11. в консоль вылетает ошибка 63, идем на почту, к которой привязан бот, туда приходит код авторизации, вставляем его в nodejs/steambot.config.js, снова запускаем приложение, должен пройти логин и в папке nodejs должен создаться файл sentry

  • 12. обновляем страницу в браузере, в сайдбаре должно писаться, что на сайте 1 человек, все ок

  • 13. запускаем бота из под forever (forever start —uid "steamboat" -a /home/ezy/steambot.js), ждем активации сервера, радуемся жизни, меняем дизайн

  •  

  • Пару замечаний:

  • — После любых правок бота его нужно перезапустить.

  • — В случае смены аккаунта необходимо ждать лишних 7 дней от стима, будьте внимательны

  • — Иногда steam лагает по вечерам, бот в таком случае тоже чехлит

  •  

  • БД — mongo

  • в случае отсутствия коллекции она создается автоматом

  • чтобы смотреть, что в БД, рекомендую установить mongo-express

  • npm -g install mongo-express

  •  

  •  момент по forever

  • npm install -g forever

  •  

  • если с винды, то через cygwin или putty

  •  

  •  

  •  

  • Тут БД смотреть:

  •  

  • http://вашдомен:8081

  • admin:фвьшт:фамтн (можно поменять в /var/www/admin/www/nodejs/node_modules/mongo-express/config.js)

  • запустить бота:

  • forever start —uid "steambot" -a /var/www/admin/www/nodejs/steambot.js

  •  

  • стопнуть бота:

  • forever stop steambot

  • перезапуск – сначала стоп, затем старт

  • это через командную строку (т.е. заходите через ssh и пишите)

  • JQuery: как обратиться из Javascript к базе данных

    Нечто подобное уже есть вот тут, но сейчас я хочу сделать AJAX-запрос покороче, с использованием именно базы MySQL, да ещё и дописать уже существующую сборку «шахматной решалки», «закрыв» в ней упомянутые по ссылке «строки 41 и 56».

    Сначала совсем простой пример, проще которого я придумать не смогу. На локальном сервере есть папка, допустим, с именем , в ней — обычный файл HTML с именем :

    <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> </head> <body> <script type="text/javascript"> var num = 5; var str = ‘Hello, world!’; $.post("./script.php", {num: num, str: str}); </script> </body></html>

    Но файл этот не совсем простой:

    • во-первых, он подключает библиотеку JQuery с сайта Гугля;
    • во-вторых, с помощью JQuery он делает из клиентского кода на Javascript запрос к серверному скрипту на PHP.

    В этой же папке лежит и файл , приём данных в нём ничем не отличается от случая, когда данные были переданы из формы HTML или от другого PHP-скрипта:

    <?php $num = 0; if (isset($_POST[‘num’])) $num = intval(strip_tags(trim($_POST[‘num’]))); $str = »; if (isset($_POST[‘str’])) $str = mysql_real_escape_string(strip_tags(trim($_POST[‘str’]))); file_put_contents ("data.txt","$num\t$str"); ?>

    Наш скрипт просто записал полученные данные в текстовый файл, отделив число от строки символом табуляции . А на самом деле мог делать с данными, полученными от клиента, что угодно, например, писать их в базу MySQL, как-то обрабатывать и т.д.

    Мы можем проверить этот код в работе, но только правильно, не щёлкая по html-файлу, а по протоколу http через браузер, скажем, разместив папку с двумя файлами в корневой папке Denwer или другого локального сервера, а затем набрав в браузере адрес

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

    Пусть к «корневому» документу HTML или скрипту PHP подключён скрипт:

    <script src="js/puzzle.js"></script>

    Неважно, что скрипт лежит во вложенной папке , всё равно вызывать серверные php-скрипты он будет из той же папки, где находится «корневой» документ, да иной подход и чреват проблемами. Например, ajax-запросы на ресурсы с доменами, поддоменами и протоколами, отличными от текущего, как правило, запрещены. То есть, из клиентского файла нельзя обратиться к серверному . А если бы было можно, любой дятел смог бы бомбить со своего компьютера любую форму в интернете. Разумеется, можно написать браузер или обёртку, где кроссдоменные ajax-запросы разрешены, но ведь порвут 🙂

    Наш клиентский , пользуясь тем, что в нём подключён JQuery, хочет иногда вызывать серверные скрипты и — для увеличения и уменьшения рейтинга юзверька в зависимости от того, правильно ли тот решает задачи:

    $.post(«./minus.php», {balM: puzzle.balM, move: correct_move}); // Отправка данных на обработку рейтинга (-) //… $.post(«./plus.php», {balP: puzzle.balP, move: correct_move}); // Отправка данных на обработку рейтинга (+)

    Это опять образец короткого вызова метода для отправки данных на сервер методом . Здесь первым параметром, с именем и , передаётся число (на сколько уменьшить или увеличить рейтинг), а вторым параметром, с именем , передаётся строка (запись хода).

    Скрипты и будут очень похожи, только первый из них не будет повторно «минусовать» неверные ходы пользователя, во втором такая проверка не нужна, так как он вызывается только после решения задачи:

    <?php require_once ‘functions.php’; $balM = intval(strip_tags(trim($_POST[‘balM’]))); $mov = mysql_real_escape_string(strip_tags(trim($_POST[‘move’]))); $ip = get_ip(); $result = dbquery(‘select * from ‘.DB_TABLE.’ where ip="’.$ip.’" limit 0,1′); if ($result and dbrows($result)) { $note = dbfetcha($result); $note[‘cnt’] -= $balM; if ($note[‘mov’]!=$mov) { //не минусовать повторно за неверные $result = dbquery(‘update ‘.DB_TABLE.’ set cnt = "’.$note[‘cnt’].’", mov = "’.$mov.’" where ip = "’.$ip.’"’); if (!$result) die (‘Invalid query 1: ‘ . mysql_error()); } } else { $result = dbquery(‘insert into ‘.DB_TABLE.’ (ip, cnt) values ("’.$ip.’", "’.(0-$balM).’")’); if (!$result) die (‘Invalid query 2: ‘ . mysql_error()); } ?><?php require_once ‘functions.php’; $balP = intval(strip_tags(trim($_POST[‘balP’]))); $ip = get_ip(); $result = dbquery(‘select * from ‘.DB_TABLE.’ where ip="’.$ip.’" limit 0,1′); if ($result and dbrows($result)) { $note = dbfetcha($result); $note[‘cnt’] += $balP; $result = dbquery(‘update ‘.DB_TABLE.’ set cnt = "’.$note[‘cnt’].’" where ip = "’.$ip.’"’); if (!$result) die (‘Invalid query 1: ‘ . mysql_error()); } else { $result = dbquery(‘insert into ‘.DB_TABLE.’ (ip, cnt) values ("’.$ip.’", "’.(0+$balP).’")’); if (!$result) die (‘Invalid query 2: ‘ . mysql_error()); } ?>

    Скрипты пользуются файлом , содержащим несложную «обёртку» для операций с базой, а также более-менее адекватную функцию определения IP-адреса пользователя:

    <?php require_once(‘config.php’); if (!isset($conid)) { function dbconnect() { $mysql=mysql_connect(DB_HOST, DB_USER, DB_PASS); //хост, логин, пароль mysql_select_db(DB_NAME); //имя базы данных return $mysql; } function dbquery ($sql) { return mysql_query($sql,get_conid()); } function dbrows ($result) { return mysql_num_rows($result); } function dbfree ($result) { mysql_free_result($result); } function dbclose ($conid) { mysql_close(get_conid()); } function dbfetcha ($result) { if ($row=mysql_fetch_assoc ($result)) return $row; else return false; } function dbfetch ($result){ if ($row=mysql_fetch_array($result)) return $row; else return false; } function get_conid () { static $conid=0; if ($conid==0) { $conid=dbconnect(); mysql_set_charset (DB_ENCODING,$conid); } return $conid; } get_conid (); } function get_ip () { if( getenv(‘HTTP_X_FORWARDED_FOR’) != » ) { $client_ip = ( !empty($_SERVER[‘REMOTE_ADDR’]) ) ? $_SERVER[‘REMOTE_ADDR’] : ( ( !empty($_ENV[‘REMOTE_ADDR’]) ) ? $_ENV[‘REMOTE_ADDR’] : $REMOTE_ADDR ); $entries = explode(‘,’, getenv(‘HTTP_X_FORWARDED_FOR’)); reset($entries); while (list(, $entry) = each($entries)) { $entry = trim($entry); if ( preg_match("/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/", $entry, $ip_list) ) { $private_ip = array(‘/^0\./’, ‘/^127\.0\.0\.1/’, ‘/^192\.168\..*/’, ‘/^172\.((1[6-9])|(2[0-9])|(3[0-1]))\..*/’, ‘/^10\..*/’, ‘/^224\..*/’, ‘/^240\..*/’); $found_ip = preg_replace($private_ip, $client_ip, $ip_list[1]); if ($client_ip != $found_ip) { $client_ip = $found_ip; break; } } } } else { $client_ip = ( !empty($_SERVER[‘REMOTE_ADDR’]) ) ? $_SERVER[‘REMOTE_ADDR’] : ( ( !empty($_ENV[‘REMOTE_ADDR’]) ) ?

    $_ENV[‘REMOTE_ADDR’] : $REMOTE_ADDR ); } return $client_ip; } ?>

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

    <?php define(‘DB_HOST’, ‘localhost’); //Хост, на котором размещен сервер MySQL define(‘DB_USER’, ‘root’); //Имя пользователя MySQL define(‘DB_PASS’, ‘root’); //Пароль пользователя MySQL define(‘DB_NAME’, ‘my’); //Имя базы данных define(‘DB_TABLE’, ‘chesspuzzles’); //Имя таблицы define(‘DB_ENCODING’, ‘cp1251’); //Кодировка базы данных ?>

    Перед тем, как запустить скрипты, я создал на локальном сервере таблицу для хранения данных. Для этого достаточно выбрать в phpMyAdmin (в Denwer он вызывается из браузера адресом ) нужную базу данных (у меня с именем ) и выполнить к ней такой SQL-запрос:

    DROP TABLE IF EXISTS chesspuzzles; CREATE TABLE IF NOT EXISTS chesspuzzles ( ip varchar(15), mov varchar(8), cnt int );

    В той же папке, где остальной PHP-код и главный файл, можно поместить скрипт , который покажет текущую статистику по IP-адресам пользователей скрипта и их баллам:

    <html><head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title>Решалка: весь рейтинг</title> </head> <body bgcolor="white"> <?php require_once ‘functions.php’; $result = dbquery(‘select * from ‘.DB_TABLE.’ order by cnt desc’); echo ‘<table align="center" width="90%" border="1" cellpadding="4" cellspacing="0">’; if ($result and dbrows($result)) { while ($note = dbfetcha($result)) { echo ‘<tr><td width="50%">’.$note[‘ip’].'</td><td>’.$note[‘cnt’].'</td></tr>’; } } else { echo ‘<tr><td>Нет данных</td></tr>’; } echo ‘</table><div align="center"><a href="list.php">Обновить</a></div>’; ?> </body></html>

    Что вышло — можно посмотреть вот тут, заодно и шахматные задачки порешать, ничего не скачивая.


    теги: javascriptшахматыphpсерверjquerymysql


    18.11.2015, 01:01; рейтинг: 10040

    Добавить комментарий

    Закрыть меню