wake-up-neo.net

MongoDB: Entspricht einem nicht leeren Dokument im Array

Ich habe eine Sammlung, die folgendermaßen aufgebaut ist:

{
  _id: 1,
  score: [
    {
      foo: 'a',
      bar: 0,
      user: {user1: 0, user2: 7}
    }
  ]
}

Ich muss alle Dokumente finden, die mindestens ein 'score' (Element im score-Array) mit einem bestimmten Wert von 'bar' und ein nicht leeres 'user'-Unterdokument aufweisen.

Folgendes habe ich mir ausgedacht (und es schien, als sollte es funktionieren):

db.col.find({score: {"$elemMatch": {bar:0, user: {"$not":{}} }}})

Aber ich bekomme diesen Fehler:

error: { "$err" : "$not cannot be empty", "code" : 13030 }

Irgendeine andere Möglichkeit, dies zu tun?

31
Dmitri

Herausgefunden: { 'score.user': { "$gt": {} } } stimmt mit nicht leeren Dokumenten überein.

61
Dmitri

Ich bin mir nicht sicher, ob ich Ihr Schema wirklich verstehe, aber der einfachste Weg wäre, keinen "leeren" Wert für score.user zu haben.

Stattdessen absichtlich nicht dieses Feld in Ihrem Dokument haben, wenn es keinen Inhalt hat?

Dann könnte Ihre Anfrage etwa so lauten ...

> db.test.find({ "score" : { "$elemMatch" : { bar : 0, "user" : {"$exists": true }}}})

dh Suche nach einem Wert inscore.bar, den Sie (in diesem Fall 0) auf das Vorhandensein von/prüfen möchten ($ existiert, siehe Dokumentation ) vonscore.user(und wenn es einen Wert hat, dann wird es existieren?)

editiert : oops, ich habe den $ elemMatch verpasst, den du hattest ...

3
Justin Jenkins

Sie möchten wahrscheinlich ein Hilfsarray hinzufügen, das die Benutzer im user-Dokument verfolgt:

{
  _id: 1,
  score: [
    {
      foo: 'a',
      bar: 0,
      users: ["user1", "user2"],
      user: {user1: 0, user2: 7}
    }
  ]
}

Dann können Sie neue Benutzer atomar hinzufügen:

> db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},                       
... {$set: {'score.$.user.user3': 10}, $addToSet: {'score.$.users': "user3"}})

Benutzer entfernen:

> db.test.update({_id: 1, score: { $elemMatch: {bar: 0}}},
... {$unset: {'score.$.user.user3': 1}, $pop: {'score.$.users': "user3"}})      

Abfrageergebnisse:

> db.test.find({_id: 1, score: {$elemMatch: {bar: 0, users: {$not: {$size: 0}}}}})

Wenn Sie wissen, dass Sie nur nicht vorhandene Benutzer hinzufügen und vorhandene Benutzer aus dem user-Dokument entfernen, können Sie users für einen Zähler anstelle eines Arrays vereinfachen.

1
cwb

Schauen Sie sich den $ size-Operator an, um die Array-Größen zu überprüfen.

0
Andreas Jung