write - Esiste un aggregato per campo MongoDB




mongodb votes (3)

Ho difficoltà a credere che questa domanda non sia stata posta e abbia già risposto da qualche parte, ma non riesco a trovarne traccia.

Ho una query di aggregazione MongoDB che deve essere raggruppata da un booleano: l'esistenza di un altro campo.

Per esempio iniziamo con questa collezione:

> db.test.find()
{ "_id" : ObjectId("53fbede62827b89e4f86c12e"),
  "field" : ObjectId("53fbede62827b89e4f86c12d"), "name" : "Erik" }
{ "_id" : ObjectId("53fbee002827b89e4f86c12f"), "name" : "Erik" }
{ "_id" : ObjectId("53fbee092827b89e4f86c131"),
  "field" : ObjectId("53fbee092827b89e4f86c130"), "name" : "John" }
{ "_id" : ObjectId("53fbee122827b89e4f86c132"), "name" : "Ben" }

2 documenti hanno "campo" e 2 no. Si noti che ciascun valore di "campo" può essere diverso; vogliamo solo raggruppare la sua esistenza (o anche la non nullità funziona per me, non ho alcun valore nullo memorizzato).

Ho provato a utilizzare $ project, ma $ esiste non esiste e $ cond e $ ifNull non mi hanno aiutato. Il campo sembra sempre esistere, anche quando non lo è:

> db.test.aggregate(
  {$project:{fieldExists:{$cond:[{$eq:["$field", null]}, false, true]}}},
  {$group:{_id:"$fieldExists", count:{$sum:1}}}
)
{ "_id" : true, "count" : 4 }

Mi aspetto che il seguente aggregato molto più semplice funzioni, ma per qualche ragione $ exists non è supportato in questo modo:

> db.test.aggregate({$group:{_id:{$exists:"$field"}, count:{$sum:1}}})
assert: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed
Error: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
    at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
    at (shell):1:9
2014-08-25T19:19:42.344-0700 Error: command failed: {
  "errmsg" : "exception: invalid operator '$exists'",
  "code" : 15999,
  "ok" : 0
} : aggregate failed at src/mongo/shell/assert.js:13

Qualcuno sa come ottenere il risultato desiderato da una collezione come questa?

Risultato atteso:

{ "_id" : true, "count" : 2 }
{ "_id" : false, "count" : 2 }


L'ho risolto con il controllo di undefined

$ne : [$var_to_check, undefined]

o

$ne:  [ { $type : "$var_to_check"}, 'missing'] }

Questo restituisce true se la var è definita


Non so come sia stato ma ora nel 2019 c'è una soluzione pulita. Nella pipeline di aggregazione fare questo

$match: {"my_field": {$ne: null}}

La cosa bella è nel mio lang 'ne' significa non :)





aggregation-framework