Frage

Angenommen, ich habe eine BlogPost Modell mit eingebetteter Zero-zu-Viele Comment Unterlagen. Kann ich MongoDB -Rendite befragen und haben nur Comment Objekte, die meine Abfragespezifikation entsprechen?

z.B, db.blog_posts.find({"comment.submitter": "some_name"}) Gibt nur eine Liste von Kommentaren zurück.

Bearbeiten: Ein Beispiel:

import pymongo

connection = pymongo.Connection()
db = connection['dvds']

db['dvds'].insert({'title': "The Hitchhikers Guide to the Galaxy",
                   'episodes': [{'title': "Episode 1", 'desc': "..."},
                                {'title': "Episode 2", 'desc': "..."},
                                {'title': "Episode 3", 'desc': "..."},
                                {'title': "Episode 4", 'desc': "..."},
                                {'title': "Episode 5", 'desc': "..."},
                                {'title': "Episode 6", 'desc': "..."}]})

episode = db['dvds'].find_one({'episodes.title': "Episode 1"}, 
                              fields=['episodes'])

In diesem Beispiel, episode ist:

{u'_id': ObjectId('...'),
 u'episodes': [{u'desc': u'...', u'title': u'Episode 1'},
               {u'desc': u'...', u'title': u'Episode 2'},
               {u'desc': u'...', u'title': u'Episode 3'},
               {u'desc': u'...', u'title': u'Episode 4'},
               {u'desc': u'...', u'title': u'Episode 5'},
               {u'desc': u'...', u'title': u'Episode 6'}]}

Aber ich will nur:

{u'desc': u'...', u'title': u'Episode 1'}
War es hilfreich?

Lösung

Dieselbe Frage wurde auf der Seite von Mongo DB Google Groups gestellt. Anscheinend ist es derzeit nicht möglich, ist aber für die Zukunft geplant.

http://groups.google.com/group/mongodb-user/browse_thread/thread/4e6f5a0bac1abccc#

Andere Tipps

Ich denke, was Sie wollten, ist Folgendes:

print db.dvds.aggregate([
  {"$unwind": "$episodes"}, # One document per episode
  {"$match": {"episodes.title": "Episode 1"} }, # Selects (filters)
  {"$group": {"_id": "$_id", # Put documents together again
              "episodes": {"$push": "$episodes"},
              "title": {"$first": "$title"} # Just take any title
             }
  },
])["result"]

Der Ausgang (neben den Whitespaces) lautet:

[ { u'episodes': [ { u'title': u'Episode 1',
                     u'desc': u'...'
                   }
                 ],
    u'_id': ObjectId('51542645a0c6dc4da77a65b6'),
    u'title': u'The Hitchhikers Guide to the Galaxy'
  }
]

Wenn Sie von der loswerden wollen u"_id", enden Sie die Pipeline mit: anhängen mit:

  {"$project": {"_id": 0,
                "episodes": "$episodes",
                "title": "$title"}
               }

Die MongoDB JavaScript -Shell ist bei dokumentiert http://docs.mongodb.org/manual/reference/method/

Wenn Sie nur bestimmte Felder eines Objekts zurückerhalten möchten, können Sie verwenden

db.collection.find( { }, {fieldName:true});

Wenn Sie andererseits nach Objekten suchen, die ein bestimmtes Feld enthalten, können Sie klagen

db.collection.find( { fieldName : { $exists : true } } );

Passen Sie einfacher zusammen:

db['dvd'].find_one( {'episodes.title': "Episode 1"},{'episodes.title': true} )

Anfrage:

coll.find( criteria, fields );

Holen Sie sich nur bestimmte Felder aus dem Objekt. Z.B:

coll.find( {}, {name:true} );

http://www.mongodb.org/display/docs/dbshell+Reference

Ansehen db.eval:

Sie sollten so etwas tun wie:

episode = connection['dvds'].eval('function(title){
  var t = db.dvds.findOne({"episodes.title" : title},{episodes:true});
  if (!t) return null;
  for (var i in t.episodes) if (t.episodes[i].title == title) return t.episodes[i];
}', "Episode 1");

Die Filterung von Episoden wird also auf einer serverseitigen Seite sein.

Ich habe auch das gleiche Problem getroffen. Ich benutze die Gesamtfunktion. Entspannen Sie es zuerst und passen Sie es dann an.

db.dvds.aggregate([{$unwind:"$episodes"},{$match:{"episodes.title":"Episode 1"}}])

Die Ergebnisse werden wie sein

{ "_id" : ObjectId("5a129c9e6944555b122c8511"),
   "title" : "The Hitchhikers Guide to the Galaxy",
   "episodes" : { "title" : "Episode 1", "desc" : "..." } }

Es ist nicht perfekt, aber dann können Sie es mit Python bearbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top