Лучший метод подсчета документов с идентификаторами объектов с использованием Mongoose?

#javascript #mongodb #mongoose

#javascript #mongodb #mongoose

Вопрос:

В настоящее время я запрашиваю MongoDB с помощью Mongoose для поиска определенной категории с определенным идентификатором объекта (например, 5ca510c87cf5db0017a59d5d), а затем подсчитываю документы в процессе с этой конкретной категорией. Однако мне интересно, есть ли лучший способ сделать это, который может запрашивать name поле (например, ‘Primary’) категории вместо этого, таким образом, он может работать в любой другой базе данных без изменения кода на определенный идентификатор.

Это Node.js приложение с Express используется для MVC и Mongoose для ODM.

Я ссылался на populate функцию Mongoose в документации, но, похоже, не могу найти хорошей аналогии.

Модель категории:

 var CategorySchema = new Schema({
    name: {type: String, required: true, min: 3, max: 100}
});
  

Модель процесса:

 var ProcessSchema = new Schema(
  {
    name: {type: String, required: true},
    machine: {type: Schema.Types.ObjectId, ref: 'Machine', required: true},
    summary: {type: String, required: true},
    serial_number: {type: String, required: true},
    category: [{type: Schema.Types.ObjectId, ref: 'Category'}]
  }
);
  

Контроллер процесса:

 exports.index = function(req, res) {

    async.parallel({
        ...
        process_category_primary_count: function(callback) {
            Process.countDocuments({category: '5ca510c87cf5db0017a59d5d'},callback);
        },
        process_category_intermediate_count: function(callback) {
            Process.countDocuments({category: '5ca510f57cf5db0017a59d5e'},callback);
        },
        process_category_finishing_count: function(callback) {
            Process.countDocuments({category: '5ca511017cf5db0017a59d5f'},callback);
        },
        ...
    }, function(err, results) {
        res.render('index', { title: 'Dashboard Home',
                              error: err,
                              data: results });
    });
};
  

По умолчанию find весь запрос для процесса выдаст результат, подобный этому:

 { category: [ 5c9d48508ee1353a2786c7d0 ],
    _id: 5ca3ca9a9743b52602d88c57,
    name: 'Milling-Detailing',
    machine: 5c9e407c6e0b26209b55dbbd,
    summary: 'Detailing pass for each object.',
    serial_number: '1002',
    __v: 0 }
  

Итак, по сути: я хотел бы использовать «имя» категории, а не «идентификатор» для поиска и подсчета коллекции процессов.

Ответ №1:

Я думаю, вам нужно было бы использовать $lookup , чтобы иметь возможность это сделать, так что это было бы немного больше кода.
Согласно документам MongoDB, .countDocuments() также выполняет агрегацию и добавляет { $group: { _id: null, count: { $sum: 1 } } } в качестве последнего этапа конвейера после того, как он соответствует переданному вами запросу. Это просто репликация того же процесса.
Он вернет курсор с одним элементом [{ _id: null, count: <someCount> }] (-:
$unwind Это category означает, что поле из массива превращается в одну запись.

 Process.aggregate([
  {
    $lookup: {
      from: 'categories',
      localField: 'category',
      foreignField: '_id',
      as: 'category'
    }
  },
  { $unwind: '$category' },
  { $match: { 'category.name': 'categoryName' } },
  { $group: { _id: null, count: { $sum: 1 } } }
], callback)
  

Комментарии:

1. Да, это работает! Добавлено в соответствии с ответом. Очень мощный, этот агрегат и поиск. Результат имеет вид [ { _id: null, count: 3 } ] . Есть ли лучший способ получить точное число (‘3’), а не нарезать результат (например, result [0].count)?

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

3. Хорошо, я попробовал это. Думаю, теперь у меня есть рабочая цепочка. Большое спасибо!