Есть ли способ подсчитать различные значения в mongoose с определенной датой отсечения

#javascript #mongodb #mongoose

#javascript #mongodb #mongoose

Вопрос:

Например, у меня есть следующие два документа

 [
   {
    "_id": "5fc534505144dd0030c44f8e",
    "createdAt": "2020-12-14T15:11:21.327Z"
    "user_id": "2",
  },
  {
    "_id": "5fc534505144dd0030c44f8e",
    "createdAt": "2020-12-14T14:10:40.427Z",
    "user_id": "1"
  },
  {
    "_id": "5fc534595144dd0030c44f95",
    "createdAt": "2020-12-13T14:10:58.027Z",
    "user_id": "1"
  }
]
 

результаты должны быть

 [
  {
    "date": "2020-12-13",
    "count":1
  },
  {
    "date": "2020-12-14",
    "count":2
  }
  ]
 

где количество — это количество отдельных документов через идентификаторы пользователей до даты, указанной в конкретной дате отсечения

Ответ №1:

данные

 data=[
   {
    "createdAt": "2020-12-14T15:11:21.327Z",
    "user_id": "2",
  },
  {
    "createdAt": "2020-12-14T14:10:40.427Z",
    "user_id": "1"
  },
  {
    "createdAt": "2020-12-13T14:10:58.027Z",
    "user_id": "1"
  },{
    "createdAt": new Date("2020-12-14T14:10:58.027Z"),
  }
]
> db.dummy.insert(data)
 

Вы можете использовать aggregate: используйте $group с _id, являющимся днем даты в сочетании с $sum)

 > db.dummy.aggregate({$group:{_id:{$substr:['$createdAt', 0, 10]}, count:{$sum:1}}})
{ "_id" : "2020-12-14", "count" : 3 }
{ "_id" : "2020-12-13", "count" : 1 }
 

редактировать: мангуст может иметь то же значение

 const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/dummy')

const UDate = mongoose.model('X', { createdAt:String, user_id: String }, 'dummy')

;(async()=>{
  mongoose.set('debug', true)
  const group = {$group:{_id:{$substr:['$createdAt', 0, 10]}, count:{$sum:1}}}
  const v = await UDate.aggregate([group])
  console.log('s : ', JSON.stringify(v))
  mongoose.disconnect()
})()
 

edit2: для обработки уникальности идентификаторов пользователей, чтобы они не считались дважды за дату, вы можете использовать $addToSet вместо суммы, за которой следует проекция с использованием $size

 
  const group = {$group:{_id:{$substr:['$createdAt', 0, 10]}, userIds:{$addToSet:'$user_id'}}}
  const count = {$project:{date:'$_id', count: {$size: '$userIds'}} }
  const v = await Stock.aggregate([group, count])
 

Наконец, если вы чувствуете, что всегда больше, вы можете «переименовать» поле _id в качестве даты во время проектирования

 {$project:{date:'$_id', _id:0, count: {$size: '$userIds'}} }
 

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

1. Мне нужно подсчитать только отдельный номер user_id, а не сумму;), который должен дать количество: 2 для 14-12

2. Сейчас у меня нет времени, в групповом конвейере вы можете использовать addToSet с user_id вместо sum, а затем добавить еще один конвейер $project, который принимает размер набора. Я в конечном итоге обновлю ответ позже

Ответ №2:

  • $gorup по createdAt дате после получения подстроки с использованием $substr и создания массива уникальных идентификаторов пользователей на основе $addToset
  • получить общий элемент в count массиве, используя $size
 db.collection.aggregate([
  {
    $group: {
      _id: { $substr: ["$createdAt", 0, 10] },
      count: { $addToSet: "$user_id" }
    }
  },
  { $addFields: { count: { $size: "$count" } } }
])
 

Игровая площадка