Per MongoDB 3.6 e versioni successive:
Il $expr
operatore consente l'uso di espressioni di aggregazione all'interno del linguaggio di query, quindi è possibile sfruttare l'uso di $dateToString
operatore per trasformare il campo della data:
db.test.find({
"$expr": {
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
}
})
o utilizzando il framework di aggregazione con $match
pipeline
db.test.aggregate([
{ "$match": {
"$expr": {
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
}
} }
])
Per MongoDB 3.0+:
Puoi anche utilizzare il framework di aggregazione con $redact
operatore della pipeline che consente di elaborare la condizione logica con $cond
operatore e utilizza le operazioni speciali $$KEEP
per "conservare" il documento in cui la condizione logica è vera o $$PRUNE
per "rimuovere" il documento in cui la condizione era falsa.
Prendi in considerazione l'esecuzione della seguente operazione di aggregazione che dimostra il concetto di cui sopra:
db.test.aggregate([
{
"$redact": {
"$cond": [
{
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Questa operazione è simile all'avere un $project
pipeline che seleziona i campi nella raccolta e crea un nuovo campo che contiene il risultato della query della condizione logica e quindi un successivo $match
, tranne che $redact
utilizza un'unica fase della pipeline che è più efficiente:
db.test.aggregate([
{
"$project": {
"created": 1,
"last_active": 1,
"sameDay": {
"$cond": [
{
"$eq": [
{"$substr" : ["$last_active",0, 10]},
{"$substr" : ["$created",0, 10]}
]
}, true, false
]
}
}
},
{ "$match": { "sameDay": false } }
])
0r
db.test.aggregate([
{
"$project": {
"created": 1,
"last_active": 1,
"sameDay": {
"$cond": [
{
"$eq": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
}, true, false
]
}
}
},
{ "$match": { "sameDay": false } }
])
Un altro approccio potrebbe essere quello di utilizzare $where
operatore nel tuo find()
metodo ma tieni presente che la query sarà piuttosto lenta poiché si utilizza $where
da solo richiede una scansione della tabella e il database esegue l'espressione o la funzione JavaScript per ogni documento nella raccolta, quindi combinare con le query indicizzate se possibile poiché le prestazioni delle query migliorano anche quando le esprimi utilizzando gli operatori MongoDB standard (ad es. $gt
, $in
):
db.test.find({
"$where": function() {
return this.created.getDate() !== this.last_active.getDate()
}
});
o più compatto:
db.test.find({ "$where": "this.created.getDate() !== this.last_active.getDate()" });
Con l'input:
/* 0 */
{
"_id" : 1,
"created" : ISODate("2014-12-19T06:01:17.171Z"),
"last_active" : ISODate("2014-12-21T15:38:13.842Z")
}
/* 1 */
{
"_id" : 2,
"created" : ISODate("2015-07-06T12:17:32.084Z"),
"last_active" : ISODate("2015-07-06T18:07:08.145Z")
}
/* 2 */
{
"_id" : 3,
"created" : ISODate("2015-07-06T06:01:17.171Z"),
"last_active" : ISODate("2015-07-07T10:04:30.921Z")
}
/* 3 */
{
"_id" : 4,
"created" : ISODate("2015-07-06T06:01:17.171Z"),
"last_active" : ISODate("2015-07-06T09:47:44.186Z")
}
/* 4 */
{
"_id" : 5,
"created" : ISODate("2013-12-19T06:01:17.171Z"),
"last_active" : ISODate("2014-01-20T13:21:37.427Z")
}
L'aggregazione restituisce:
/* 0 */
{
"result" : [
{
"_id" : 1,
"created" : ISODate("2014-12-19T06:01:17.171Z"),
"last_active" : ISODate("2014-12-21T15:38:13.842Z"),
"sameDay" : false
},
{
"_id" : 3,
"created" : ISODate("2015-07-06T06:01:17.171Z"),
"last_active" : ISODate("2015-07-07T10:04:30.921Z"),
"sameDay" : false
},
{
"_id" : 5,
"created" : ISODate("2013-12-19T06:01:17.171Z"),
"last_active" : ISODate("2014-01-20T13:21:37.427Z"),
"sameDay" : false
}
],
"ok" : 1
}