Vous aurez besoin de $elemMatch et aggregate .
db.users.aggregate([
{
$unwind: "$Sessions"
},
{
$match: {
"Sessions.Last_Login": {
$gte: ISODate("2016-06-16T00:00:00.0Z"),
$lt: ISODate("2016-06-17T00:00:00.0Z")
}
}
},
{
$group: {
_id: {
_id: "$_id",
First_Name: "$First_Name",
Last_Name: "$Last_Name"
},
Sessions: {
$push: "$Sessions"
}
}
},
{
$project: {
_id: "$_id._id",
First_Name: "$_id.First_Name",
Last_Name: "$_id.Last_Name",
Sessions: "$Sessions"
}
}
])
La requête effectuera donc ces étapes :
$unwind
toutes lesSessions
éléments$match
documents dans la plage de dates$group
regrouper les documents par_id
,First_Name
,Last_Name
$project
documents pour qu'ils ressemblent au format d'origine
J'ai omis certains champs, mais vous pouvez facilement l'ajouter dans $group
et $project
pas. Et bien sûr, vous devrez modifier la plage de dates.
Je suis préoccupé par les performances de cette requête dans une grande collection. Peut-être est-il préférable d'utiliser la première requête que j'ai donnée et de filtrer les sessions souhaitées dans votre code.
Modifier :
Comme @chridam l'a dit, cette requête ne fonctionnera que si vous modifiez Last_Login
à ISODate()
, ce qui est recommandé.
Modification 2 :
Mise à jour de la requête pour utiliser aggregate
et correspond à la demande de récupérer uniquement Sessions
à l'intérieur de la plage de dates.
Ceci est l'ancienne version :
db.users.filter({
'Sessions': {
'$elemMatch': {
'Last_Login': {
'$gte': ISODate("2016-06-16T00:00:00.0Z"),
'$lt': ISODate("2016-06-17T00:00:00.0Z")
}
}
}
})