MongoDB -Abfrage, um nur eingebettetes Dokument zurückzugeben
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'}
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} );
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.