Запрос на месяц внутри массива MongoDB

#mongodb #mongoose #mongodb-query

#mongodb — монгодб #mongoose #mongodb-запрос #mongodb

Вопрос:

Проблема, которую я пытаюсь решить, заключается в запросе массива документов с использованием функции модели поиска mongoose. Мои документы выглядят примерно так:

 {
  name: "John",
  courses: [
    {
      name: "CS",
      enrolled: 2015-12-12T00:00:00.000 00:00,
      ...,
    },
    {
      name: "Math",
      enrolled: 2016-10-12T00:00:00.000 00:00,
      ...,
    },
    {
      name: "History",
      enrolled: 2017-09-12T00:00:00.000 00:00,
      ...,
    },
    ...,
  ]
}
  

Итак, проблема здесь в том, что я пытаюсь запросить все те документы, в которых один из вложенных документов в массиве имеет поле «зарегистрирован», которое соответствует определенному месяцу для даты, которую он содержит. Например, найдите все документы, в которых человек записался на курс в декабре (месяц 12)

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

{$expr: {$eq: [{$month: "$enroll"}, 12]}}

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

Есть идеи о том, как действовать дальше? Спасибо!

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

1. Вы не можете, потому что, когда вы используете позиционный оператор $ в find(), это выдаст только одну совпадающую находку в результате проверки , вам нужно использовать aggregate()

2. Хорошо, спасибо вам всем. В итоге изменилась структура моего документа….

Ответ №1:

Поскольку у вас возникли проблемы с запросом, вы можете использовать $filter для удаления нежелательных объектов.

 {
    "$project": {
      name: 1,
      courses: {
        $filter: {
          input: "$courses",
          cond: {
            $eq: [
              "$$this.enrolled",
              "2016-10-12T00:00:00.000 00:00"
            ]
          }
        }
      }
    }
  }
  

Работает игровая площадка Mongo

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

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

2. Я не думаю, что могут быть какие-то способы обойтись без агрегации

Ответ №2:

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

Запрос:

 db.collection.aggregate([
  {
    $addFields: {
      coursesCopy: "$courses"
    }
  },
  {
    "$unwind": "$courses"
  },
  {
    "$match": {
      "$expr": {
        "$eq": [
          {
            "$month": "$courses.enrolled"
          },
          12
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      courses: {
        $first: "$coursesCopy"
      }
    }
  }
]);
  

Ссылка на игровую площадку -Демо