Найти самые последние данные за день - PullRequest
0 голосов
/ 20 сентября 2018

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

Моя структура базы данных выглядит следующим образом

{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{}],
        "user": "user10",
        "date" : "2018-09-09 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-10 10:58:18"
}

Мне удалось приблизиться к нужному поведению, сгруппировав дату и получив последнюю извлеченную дату, например:

{ "_id" : "2018-09-15 00:00:00", "extracted_date" : "2018-09-19 13:50:22" }
{ "_id" : "2018-09-16 00:00:00", "extracted_date" : "2018-09-19 13:47:26" }
{ "_id" : "2018-09-17 00:00:00", "extracted_date" : "2018-09-19 13:45:00" }
{ "_id" : "2018-09-11 00:00:00", "extracted_date" : "2018-09-12 10:09:17" }
{ "_id" : "2018-09-12 00:00:00", "extracted_date" : "2018-09-14 15:34:59" }
{ "_id" : "2018-09-14 00:00:00", "extracted_date" : "2018-09-19 13:54:34" }
{ "_id" : "2018-09-13 00:00:00", "extracted_date" : "2018-09-14 15:36:10" }
{ "_id" : "2018-09-18 00:00:00", "extracted_date" : "2018-09-19 13:42:23" }

Но когда я группирую данные, яв итоге получаю все значения с того дня, а мне нужен только последний.Вот пример запроса, который я использовал:

db.collection.aggregate({'$match': {'type': 'user', 'date': {'$gte': '2018-09-11 00:00:00', '$lte': '2018-09-18 00:00:00'}}}, {'$group': {'_id': {'type': '$type', 'user': '$user', 'date': '$date'}, 'extracted_date': {'$last': '$extracted_date'}, 'values': {'$push': '$values'}}})

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

Большое спасибо за вашу помощь!

Редактировать: Мне нужен пример этого случая.

объекты базы данных:

{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{'field1': 1, 'field2': 3}],
        "user": "user10",
        "date" : "2018-09-09 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-10 10:58:18"
}
{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{'field1': 1, 'field2': 4}],
        "user": "user10",
        "date" : "2018-09-09 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-11 10:58:18"
}
{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{'field11': 2, 'field2': 10}],
        "user": "user11",
        "date" : "2018-09-05 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-10 10:58:18"
}

Ожидаемое возвращение:

{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{'field1': 1, 'field2': 4}],
        "user": "user10",
        "date" : "2018-09-09 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-11 10:58:18"
}
{
        "_id" : ObjectId("5b96787ebe9d44528eaa18a0"),
        "values" : [{'field11': 2, 'field2': 10}],
        "user": "user11",
        "date" : "2018-09-05 00:00:00",
        "type" : "patient",
        "extracted_date" : "2018-09-10 10:58:18"
}

Поскольку существует2 возражает от той же даты, он возвращает только тот, с самой последней извлеченной датой

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Думаю, вы путаете между 'последним в день' (тем, который добавлялся позднее каждого дня) и $ last (последним из предыдущего этапа в конвейере)!

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

db.collection.aggregate({
  "$match": {
    "type": "user",
    "date": {
      "$gte": "2018-09-11 00:00:00",
      "$lte": "2018-09-18 00:00:00"
    }
  }
}, 
{$sort:{
  date:1,
  extracted_date:1
}
},
{
  "$group": {
    "_id": {
      "type": "$type",
      "user": "$user",
      "date": "$date"
    },
    "extracted_date": {
      "$last": "$extracted_date"
    },
    "values": {
      "$last": "$values"
    }
  }
})
0 голосов
/ 20 сентября 2018

Если я вас правильно понимаю, вы хотите просто получить массив last values, а не все из них за этот день вместе взятые ...

Так что просто сделайте $last для таких значений, как высделал для extracted_date.

ОБНОВЛЕНИЕ :

Поскольку вы ищете самые последние данные для этого диапазона, вам нужно использовать sort согласно matthPen предложение и просто получить необходимые поля из _id, а затем скрыть _id:

db.collection.aggregate([{
    "$match": {
      "type": "patient",
      "date": {
        "$gte": "2018-09-05 00:00:00",
        "$lte": "2018-09-18 00:00:00"
      }
    }
  },
  {
    "$sort": {
      "extracted_date": 1
    }
  },
  {
    "$group": {
      "_id": {
        "type": "$type",
        "user": "$user",
        "date": "$date"
      },
      "id": {
        $last: "$_id"
      },
      "date": {
        $last: "$date"
      },
      "type": {
        $last: "$type"
      },
      "extracted_date": {
        $last: "$extracted_date"
      },
      "values": {
        $last: "$values"
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  }
])

Вы можете увидеть это здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...