Untuk MongoDB 3.6 dan yang lebih baru:
$expr
operator mengizinkan penggunaan ekspresi agregasi dalam bahasa kueri, sehingga Anda dapat memanfaatkan penggunaan $dateToString
operator untuk mengubah bidang tanggal:
db.test.find({
"$expr": {
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
}
})
atau menggunakan kerangka kerja agregasi dengan $match
pipa
db.test.aggregate([
{ "$match": {
"$expr": {
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
}
} }
])
Untuk MongoDB 3.0+:
Anda juga dapat menggunakan kerangka kerja agregasi dengan $redact
operator pipa yang memungkinkan Anda memproses kondisi logis dengan $cond
operator dan menggunakan operasi khusus $$KEEP
untuk "menyimpan" dokumen dengan kondisi logika benar atau $$PRUNE
untuk "menghapus" dokumen yang kondisinya salah.
Pertimbangkan untuk menjalankan operasi agregat berikut yang menunjukkan konsep di atas:
db.test.aggregate([
{
"$redact": {
"$cond": [
{
"$ne": [
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$created" } },
{ "$dateToString": { "format": "%Y-%m-%d", "date": "$last_active" } }
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
Operasi ini mirip dengan memiliki $project
pipa yang memilih bidang dalam koleksi dan membuat bidang baru yang menyimpan hasil dari kueri kondisi logis dan kemudian $match
, kecuali $redact
menggunakan satu tahap pipeline yang lebih efisien:
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 } }
])
Pendekatan lain adalah dengan menggunakan $where
operator di find()
. Anda tetapi perhatikan bahwa kueri akan cukup lambat karena menggunakan $where
saja memerlukan pemindaian tabel dan database mengeksekusi ekspresi atau fungsi JavaScript untuk setiap dokumen dalam koleksi, jadi gabungkan dengan kueri yang diindeks jika Anda bisa karena kinerja kueri juga meningkat saat Anda mengekspresikannya menggunakan operator MongoDB standar (mis., $gt
, $in
):
db.test.find({
"$where": function() {
return this.created.getDate() !== this.last_active.getDate()
}
});
atau lebih ringkas:
db.test.find({ "$where": "this.created.getDate() !== this.last_active.getDate()" });
Dengan masukan:
/* 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")
}
Agregasi kembali:
/* 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
}