Mongodb (Mongoose) проблема с возвратом массива строк, который соответствует существующим коллекциям в базе данных - PullRequest
0 голосов
/ 29 августа 2018

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

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

Как я могу изменить это, чтобы получить ожидаемый результат?

function getCollectionNames() {
    mongoose.connect(uri, { useNewUrlParser: true })
    const db = mongoose.connection

    db.on('error', console.error.bind(console, 'Connection error:'))

    db.once('open', () => {
        return mongoose.connection.db.listCollections().toArray().then( (collections) => {
            let names = [] 
            collections.forEach( (col) => { names.push(col.name) })
            mongoose.connection.close()
            return names
        }) 
    })
}

getCollectionNames() // Should return an array of strings.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Все ваши операции с БД асинхронны, поэтому, когда ваша функция возвращается, эти операции не завершены (и, возможно, даже не запущены).

Это статья , которая прекрасно понимает, как JS обрабатывает асинхронный код.

Также вам может понадобиться понять функции стрелок , чтобы понять код ниже.

Я не знаю, знакомы ли вы с Promise s, если нет, вот хорошая ссылка .

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

  • подключиться к вашей БД
  • получить данные и обработать их

Сначала подключитесь к вашей базе данных (это асинхронная операция):

const mongoose = require( 'mongoose' ); 

// just call it once to connect to your DB
const connectToMongoDB = uri => new Promise((resolve, reject) => {
  mongoose.connect(uri, { useNewUrlParser: true }); 
  const mongooseCo = mongoose.connection;

  mongooseCo.on('error', err => reject(err))
  mongooseCo.once('open', () => resolve(mongooseCo));
});

Когда это Обещание разрешается, это означает, что ваше соединение с БД открыто (.once('open'))

Вот как использовать эту функцию:

connectToMongoDB(YOUR_DB_URI)
  .then(db => {
    /* do what you want with your db */
  })
  .catch(e => { /* the connection throws an error : e */ })

ОК, теперь вам нужно получить данные из вашей БД и извлечь их. Процесс тот же: создайте функцию, которая возвращает обещание, и разрешите обещание, чтобы получить значение.

const getMyCollections = mongooseCo => new Promise((resolve, reject) => {
  mongooseCo.db.listCollections().toArray().then(collections => {
    const names = collections.map(col => col.name);
    resolve(names);
  })
});

Вот как это использовать:

getMyCollections(mongoose.connection)
  .then(names => { /* Do what you want with your names */ })

Как заставить это работать вместе

connectToMongoDB(YOUR_DB_URI)
  .then(mongooseCo => {
     getMyCollections(mongooseCo)
       .then(names => {
         /* do what you want with your names */
        })
   })

Лучше использовать Цепочка обещаний :

connectToMongoDB(YOUR_DB_URI)
  .then(getMyCollections)
  .then(names => {
    /* here are your names */
   })

Надеюсь, это поможет,
С наилучшими пожеланиями

0 голосов
/ 29 августа 2018

Попробуйте запустить функцию имен коллекций после подключения.

'mongoose.connection.on('open', function (ref) {
    console.log('Connected to mongo server.');
    //trying to get collection names
    mongoose.connection.db.collectionNames(function (err, names) {
        console.log(names); // [{ name: 'dbname.myCollection' }]
        module.exports.Collection = names;
    });
})'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...