Node.js, соединяющийся с MongoDB с обещаниями [дубликат]

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

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

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

58
задан tereško 8 July 2014 в 07:39
поделиться

6 ответов

Вот как я это делаю с современным синтаксисом, основанным на примере go-oleg.

Я добавил несколько комментариев в код.

./ db / mongodb.js

 const MongoClient = require('mongodb').MongoClient
 const uri = 'mongodb://user:password@localhost:27017/dbName'
 let _db

 const connectDB = async (callback) => {
     try {
         MongoClient.connect(uri, (err, db) => {
             _db = db
             return callback(err)
         })
     } catch (e) {
         throw e
     }
 }

 const getDB = () => _db

 const disconnectDB = () => _db.close()

 module.exports = { connectDB, getDB, disconnectDB }
< blockquote>

./ index.js

 // Load MongoDB utils
 const MongoDB = require('./db/mongodb')
 // Load queries & mutations
 const Users = require('./users')

 // Improve debugging
 process.on('unhandledRejection', (reason, p) => {
     console.log('Unhandled Rejection at:', p, 'reason:', reason)
 })

 const seedUser = {
     name: 'Bob Alice',
     email: 'test@dev.null',
     bonusSetting: true
 }

 // Connect to MongoDB and put server instantiation code inside
 // because we start the connection first
 MongoDB.connectDB(async (err) => {
     if (err) throw err
     // Load db & collections
     const db = MongoDB.getDB()
     const users = db.collection('users')

     try {
         // Run some sample operations
         // and pass users collection into models
         const newUser = await Users.createUser(users, seedUser)
         const listUsers = await Users.getUsers(users)
         const findUser = await Users.findUserById(users, newUser._id)

         console.log('CREATE USER')
         console.log(newUser)
         console.log('GET ALL USERS')
         console.log(listUsers)
         console.log('FIND USER')
         console.log(findUser)
     } catch (e) {
         throw e
     }

     const desired = true
     if (desired) {
         // Use disconnectDB for clean driver disconnect
         MongoDB.disconnectDB()
         process.exit(0)
     }
     // Server code anywhere above here inside connectDB()
 })

./ users / index.js

 const ObjectID = require('mongodb').ObjectID

 // Notice how the users collection is passed into the models
 const createUser = async (users, user) => {
     try {
         const results = await users.insertOne(user)
         return results.ops[0]
     } catch (e) {
         throw e
     }
 }

 const getUsers = async (users) => {
     try {
         const results = await users.find().toArray()
         return results
     } catch (e) {
         throw e
     }
 }

 const findUserById = async (users, id) => {
     try {
         if (!ObjectID.isValid(id)) throw 'Invalid MongoDB ID.'
         const results = await users.findOne(ObjectID(id))
         return results
     } catch (e) {
         throw e
     }
 }

 // Export garbage as methods on the Users object
 module.exports = { createUser, getUsers, findUserById }
4
ответ дан agm1984 19 August 2018 в 05:03
поделиться
  • 1
    нужен ли улов try в вашем первом фрагменте? функция подключения является асинхронной. Ошибка уже улавливается с помощью обратного вызова стиля узла. – shanks 16 May 2018 в 21:44
  • 2
    Это очень замечательный вопрос, который я люблю. Я не уверен, не изучая его ближе в среде обитания, где вы размещаете код. Будет ограниченное количество путей, которые могут потребоваться при выполнении кода. Я добавил его в основном, чтобы показать, что вы можете поставить пользовательский обработчик и потому, что я по умолчанию включаю try / catch в async-функции. Это просто точка крючка. Хороший вопрос. Я обновлю, если вы найдете дополнительную заметку. – agm1984 17 May 2018 в 22:08

Вы можете создать модуль mongoUtil.js, который имеет функции как для подключения к mongo, так и для возврата экземпляра mongo db:

var MongoClient = require( 'mongodb' ).MongoClient;

var _db;

module.exports = {

  connectToServer: function( callback ) {
    MongoClient.connect( "mongodb://localhost:27017/marankings", function( err, db ) {
      _db = db;
      return callback( err );
    } );
  },

  getDb: function() {
    return _db;
  }
};

Чтобы использовать его, вы сделаете это в своем app.js:

var mongoUtil = require( 'mongoUtil' );

mongoUtil.connectToServer( function( err ) {
  // start the rest of your app here
} );

И тогда, когда вам нужен доступ к mongo где-нибудь, вы можете сделать это:

var mongoUtil = require( 'mongoUtil' );
var db = mongoUtil.getDb();

db.collection( 'users' ).find();

Причина этого в том, что в узле, когда модули require 'd, они только загружаются / получаются один раз, так что вы только когда-нибудь закончите с одним экземпляром _db, а mongoUtil.getDb() всегда вернет тот же самый экземпляр.

Примечание, код не проверен.

86
ответ дан go-oleg 19 August 2018 в 05:03
поделиться
  • 1
    Отличный пример! Однако у меня есть вопрос. Как это будет работать при запуске вашего приложения с несколькими кластерами? Разве это запустит другой экземпляр подключения или просто использует существующее соединение из источника? – Farhan Ahmad 9 February 2015 в 03:59
  • 2
    Работает как шарм, спасибо! – Arpit 23 December 2016 в 17:26
  • 3
    Как вы справитесь с тем случаем, когда соединение монго будет умирать между ними? Все вызовы getDb () не будут выполняться в этом сценарии до тех пор, пока приложение узла не будет перезапущено. – Ayan 22 August 2017 в 12:02
  • 4
    Я пробовал этот код, но я получил null, когда делаю mongoUtil.getDb (), я не знаю, почему это так. – Keming 17 January 2018 в 20:44
  • 5
    @KemingZeng - вам нужно убедиться, что все модули, которые используют mongoUtil, импортируются в app.js в функции обратного вызова из connectToServer. Если вы require их в app.js до _db установлены, то вы получите неопределенные ошибки в других модулях. – Mike 17 February 2018 в 22:40
  • 6
    – Julian Veerkamp 23 August 2018 в 12:01

go-oleg в принципе прав, но в эти дни вы (вероятно) не хотите использовать «mongodb» самостоятельно, скорее используйте некоторую фреймворк, которая сделает для вас много «грязной работы».

Например, мангуст является одним из самых распространенных. Это то, что мы имеем в нашем исходном файле server.js:

const mongoose = require('mongoose');
const options = {server: {socketOptions: {keepAlive: 1}}};
mongoose.connect(config.db, options);

Это все, что необходимо для его настройки. Теперь используйте это в любом месте вашего кода

const mongoose = require('mongoose');

И вы получите тот экземпляр, который вы установили с помощью mongoose.connect

4
ответ дан libik 19 August 2018 в 05:03
поделиться
  • 1
    Мангуста - это ОРМ. Прочитайте этот , чтобы узнать о возможных ловушках для того же самого. Без сомнения, ORM великолепны при использовании для процесса развития и обучения, но не для производства. Просто помните об этом – Saras Arya 13 April 2017 в 14:16
  • 2
    Mongoose также требует схем. Я использую пакет MongoDB как часть сохранения многоугольника с Neo4j, поэтому неплохо определить свойства документа по мере необходимости. – agm1984 24 July 2017 в 06:10

Если вы используете Express, то вы можете использовать модуль express-mongo-db , который позволяет вам получить соединение db в объекте запроса.

Установить

npm install --save express-mongo-db

server.js

var app = require('express')();

var expressMongoDb = require('express-mongo-db');
app.use(expressMongoDb('mongodb://localhost/test'));

routes / users.js

app.get('/', function (req, res, next) {
    req.db // => Db object
});
8
ответ дан Mukesh Chapagain 19 August 2018 в 05:03
поделиться

Проверенное решение на основе принятого ответа:

mongodbutil.js:

var MongoClient = require( 'mongodb' ).MongoClient;
var _db;
module.exports = {
  connectToServer: function( callback ) {
    MongoClient.connect( "<connection string>", function( err, client ) {
      _db = client.db("<collection name>");
      return callback( err );
    } );
  },
  getDb: function() {
    return _db;
  }
};

app.js :

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

var mongodbutil = require( './mongodbutil' );
mongodbutil.connectToServer( function( err ) {
  //app goes online once this callback occurs
  var indexRouter = require('./routes/index');
  var usersRouter = require('./routes/users');
  var companiesRouter = require('./routes/companies');
  var activitiesRouter = require('./routes/activities');
  var registerRouter = require('./routes/register');  
  app.use('/', indexRouter);
  app.use('/users', usersRouter);
  app.use('/companies', companiesRouter);
  app.use('/activities', activitiesRouter);
  app.use('/register', registerRouter);  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
    next(createError(404));
  });
  // error handler
  app.use(function(err, req, res, next) {
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
    res.status(err.status || 500);
    res.render('error');
  });
  //end of calback
});

module.exports = app;

activities.js - маршрут:

var express = require('express');
var router = express.Router();
var mongodbutil = require( '../mongodbutil' );
var db = mongodbutil.getDb();

router.get('/', (req, res, next) => {  
    db.collection('activities').find().toArray((err, results) => {
        if (err) return console.log(err)
            res.render('activities', {activities: results, title: "Activities"})
    });
});

router.post('/', (req, res) => {
  db.collection('activities').save(req.body, (err, result) => {
    if (err) return console.log(err)
    res.redirect('/activities')
  })
});

module.exports = router;

0
ответ дан steve 19 August 2018 в 05:03
поделиться
1
ответ дан Henry Bothin 30 October 2018 в 16:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: