MongoDB -Как получить дату последних 30 дней от данной даты, и эта дата последних 30 дней должна быть текущей датой? - PullRequest
0 голосов
/ 02 марта 2020

Я новичок в MongoDB

Здесь я упомянул ниже мой единственный документ

{
"_id" : ObjectId("5e5bc292361b710c7727718e"),
"branch_id" : "BR5cc825dac42dac3aae49ff91",
"inventory" : [ 
    {
        "inventory_stock_id" : "wewe123",
        "stock_name" : "xxxxx",
        "stock_point" : "27",
        "stock_type" : "yyyy",
        "batch" : [ 
            {
                "quantity" : 40,
                "manf_date" : "10-01-2020",
                "exp_date" : "01-04-2020"
            }
        ]
    }
]
}

Я хочу получить последние 30 дней из "exp_date" , но это должно быть равно текущая дата

Здесь я упомянул exp_date: "01-04-2020" и последние 30 дней даты сегодняшняя дата ( "02-03-2020" )

db.collection.find({"inventory.batch.exp_date" : {"$lte":"01-04-2020","$eq":"02-03-2020"}})

Я не знаю, как получить последние 30 дней exp_date и равные текущей дате

поэтому кто-нибудь поможет мне решить эту проблему.

1 Ответ

0 голосов
/ 03 марта 2020

Обычно неправильно хранить / сравнивать Date значения в виде строк.

Вы можете сделать это следующим образом. Сначала преобразуйте строки в соответствующие Date объекты:

db.collection.updateMany(
   {},
   [
      {
         $set: {
            inventory: {
               $map: {
                  input: "$inventory",
                  as: "inventory",
                  in: {
                     $mergeObjects: [
                        "$$inventory",
                        {
                           batch: {
                              $map: {
                                 input: "$$inventory.batch",
                                 in: {
                                    quantity: "$$this.quantity",
                                    manf_date: { $dateFromString: { dateString: "$$this.manf_date", format: "%d-%m-%Y" } },
                                    exp_date: { $dateFromString: { dateString: "$$this.exp_date", format: "%d-%m-%Y" } }
                                 }
                              }
                           }
                        }
                     ]
                  }
               }
            }
         }
      }
   ]
)

Когда вам нужно работать со значениями Date, тогда я рекомендую библиотеку Moment. js. Запрос будет выглядеть следующим образом:

db.collection.find(
   {
      "inventory.batch": {
         $elemMatch: {
            exp_date: {
               $eq: moment().utc().add(30, 'days').startOf('day').toDate()
            }
         }
      }
   }
)

или в виде агрегации:

db.collection.aggregate([
   {
      $match: {
         "inventory.batch": {
            $elemMatch: {
               exp_date: {
                  $eq: moment().utc().add(30, 'days').startOf('day').toDate()
               }
            }
         }
      }
   }
])

Обратите внимание, по умолчанию $dateFromString использует UT C раз, тогда как moment() по умолчанию использует ваше местное время. Таким образом, вы должны использовать либо moment().utc(), либо указать поле timezone в $dateFromString.

. Если вы настаиваете на сохранении строковых значений в качестве даты, вы также можете использовать

db.collection.find(
   {
      "inventory.batch": {
         $elemMatch: {
            exp_date: {
               $eq: moment().add(30, 'days').startOf('day').format("DD-MM-YYYY")
            }
         }
      }
   }
)

Однако это не удастся, если вы запросите с $gte, $ge, $lt, $lte операторами.

Обновите

Если у вас нет доступа к moments, вы можете запустить в чисто в агрегации:

db.collection.aggregate([
   { $unwind: "$inventory" },
   { $set: { ts: { $dateToParts: { date: { $add: ["$$NOW", { $multiply: [1000, 60, 60, 24, 30] }] } } } } },
   {
      $set: {
         ts: {
            $dateFromParts: {
               year: "$ts.year",
               month: "$ts.month",
               day: "$ts.day",
               timezone: "UTC"
            }
         }
      }
   },
   { $set: { matches: { $in: ["$ts", "$inventory.batch.exp_date"] } } },
   {
      $group: {
         _id: { _id: "$_id", branch_id: "$branch_id" },
         inventory: { $push: "$$ROOT.inventory" },
         matches: { $push: "$$ROOT.matches" }
      }
   },
   { $match: { $expr: { $anyElementTrue: "$matches" } } },
   { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$_id"] } } },
   {$unset: "matches"}
])

или, если вы хотите написать все в одной агрегации:

db.collection.aggregate([
   { $unwind: "$inventory" },
   {
      $set: {
         "inventory.batch": {
            $map: {
               input: "$inventory.batch",
               in: {
                  quantity: "$$this.quantity",
                  manf_date: { $dateFromString: { dateString: "$$this.manf_date", format: "%d-%m-%Y" } },
                  exp_date: { $dateFromString: { dateString: "$$this.exp_date", format: "%d-%m-%Y" } }
               }
            }
         }
      }
   },
   { $set: { ts: { $dateToParts: { date: { $add: ["$$NOW", { $multiply: [1000, 60, 60, 24, 30] }] } } } } },
   {
      $set: {
         ts: {
            $dateFromParts: {
               year: "$ts.year",
               month: "$ts.month",
               day: "$ts.day",
               timezone: "UTC"
            }
         }
      }
   },
   { $set: { matches: { $in: ["$ts", "$inventory.batch.exp_date"] } } },
   {
      $group: {
         _id: { _id: "$_id", branch_id: "$branch_id" },
         inventory: { $push: "$$ROOT.inventory" },
         matches: { $push: "$$ROOT.matches" }
      }
   },
   { $match: { $expr: { $anyElementTrue: "$matches" } } },
   { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$_id"] } } },
   { $unset: "matches" }
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...