requête MongoDB pour revenir seul document intégré
Question
supposer que j'ai un modèle BlogPost
avec zéro à de nombreux documents Comment
embarqués. puis-je interroger et avoir le retour MongoDB uniquement objets Comment
correspondant à ma requête spec?
par exemple, db.blog_posts.find({"comment.submitter": "some_name"})
renvoie uniquement une liste de commentaires.
edit: un exemple:
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'])
dans cet exemple, episode
est:
{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'}]}
mais je veux juste:
{u'desc': u'...', u'title': u'Episode 1'}
La solution
On a posé cette même question sur la page Google Groupes DB Mongo. Apparemment, ce ne est pas possible actuellement, mais il est prévu pour l'avenir.
http://groups.google.com/group/mongodb -user / browse_thread / fil / 4e6f5a0bac1abccc #
Autres conseils
Je pense que ce que vous vouliez est ceci:
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"]
La sortie (en plus des espaces blancs) est la suivante:
[ { u'episodes': [ { u'title': u'Episode 1',
u'desc': u'...'
}
],
u'_id': ObjectId('51542645a0c6dc4da77a65b6'),
u'title': u'The Hitchhikers Guide to the Galaxy'
}
]
Si vous voulez vous débarrasser de la u"_id"
, ajoutez le pipeline avec:
{"$project": {"_id": 0,
"episodes": "$episodes",
"title": "$title"}
}
Le shell javascript MongoDB est documenté http://docs.mongodb.org/manual / référence / procédé /
Si vous voulez revenir seulement des domaines spécifiques d'un objet, vous pouvez utiliser
db.collection.find( { }, {fieldName:true});
Si, d'autre part, vous êtes à la recherche d'objets qui contiennent un champ spécifique, vous pouvez poursuivre
db.collection.find( { fieldName : { $exists : true } } );
Match simple:
db['dvd'].find_one( {'episodes.title': "Episode 1"},{'episodes.title': true} )
Requête:
coll.find( criteria, fields );
Obtenir des champs spécifiques de l'juste objet. .: par exemple
coll.find( {}, {name:true} );
Regardez db.eval :
Vous devriez faire quelque chose comme:
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");
si le filtrage des épisodes sera sur un côté serveur.
J'ai aussi rencontré le même problème. La façon dont je fais est d'utiliser la fonction globale. Tout d'abord se détendre et ensuite correspondre.
db.dvds.aggregate([{$unwind:"$episodes"},{$match:{"episodes.title":"Episode 1"}}])
Les résultats seront comme
{ "_id" : ObjectId("5a129c9e6944555b122c8511"),
"title" : "The Hitchhikers Guide to the Galaxy",
"episodes" : { "title" : "Episode 1", "desc" : "..." } }
Il est pas parfait, mais vous pouvez le modifier en python.