преобразование последовательности данных во вложенный массив объектов (MongoDB)

#javascript #node.js #mongodb #mongodb-query

Вопрос:

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

Мои коллекции:

 {
    sections: [{
            fields: [{
                    name: 'Date',
                    value: '2020-11-30T15:59:59.999Z' // this is string 
                },
                {
                    name: 'Title',
                    value: 'My book' 
                },
                {
                    name: 'Author',
                    value: 'Henry'
                }
            ]
        ]
    }
}
 

Что я пробовал:

1)

 const existingReport = await Report.find({
      $expr: {
        $gte: [
          {
            $dateFromString: {
              dateString: "$sections.field[0].value",
            },
          },
          moment(payload.forPeriod).startOf("month").toDate(),
        ],
        $lt: [
          {
            $dateFromString: {
              dateString: "$sections.field[0].value",
            },
          },
          moment(payload.forPeriod).endOf("month").toDate(),
        ],
      },
    });
 
 const existingReport1 = await Report.aggregate([
      {
        $addFields: {
          formattedData: {
            $cond: {
              if: {
                $eq: ["$sections.field.value", "Date"],
              },
              then: {
                $dateFromString: {
                  dateString: "$sections.field.value",
                },
              },
              else: "$sections.field.value",
            },
          },
        },
      },
    ]);
 

Ответ №1:

Вы можете просто выполнить a $toDate с помощью 2 $reduce для повторения sections fields массива и.

 db.collection.aggregate([
  {
    "$match": {
      $expr: {
        $eq: [
          true,
          {
            "$reduce": {
              "input": "$sections",
              "initialValue": false,
              "in": {
                "$reduce": {
                  "input": "$this.fields",
                  "initialValue": false,
                  "in": {
                    $or: [
                      "$value",
                      {
                        $and: [
                          {
                            $gte: [
                              {
                                "$toDate": "$this.value"
                              },
                              new Date("2020-11-01")
                            ]
                          },
                          {
                            $lte: [
                              {
                                "$toDate": "$this.value"
                              },
                              new Date("2020-11-30")
                            ]
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
])
 

Вот игровая площадка Монго для вашей справки.

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

1. Я все еще не могу отфильтровать правильные документы. Я отредактировал предоставленную вами игровую площадку, возможно, вы поможете мне взглянуть, спасибо. mongoplayground.net/p/gwFVoi_miW_

2. @Thomas обновил ответ, чтобы использовать $reduce его в соответствии с вашими потребностями.

3. спасибо за вашу помощь, но как только я изменил дату, произошла ошибка

4. в чем сообщение об ошибке? и каково ваше последнее испытание?

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