2010-02-15 2 views
15

Предположим, что у меня есть модель BlogPost со встроенными Comment документами. я могу запросить и вернуть MongoDB толькоComment объектов, соответствующих моему запросу spec?MongoDB запрос на возврат только встроенного документа

например, db.blog_posts.find({"comment.submitter": "some_name"}) возвращает только список комментариев.

редактировать: пример:

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']) 

в этом примере, episode является:

{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'}]} 

, но я просто хочу:

{u'desc': u'...', u'title': u'Episode 1'} 
+0

«Будущее» принятого ответа - это прошлое, поскольку структура агрегации уже существует. Я ответил, как это сделать. –

ответ

2

MongoDB Javascript оболочка документированы http://docs.mongodb.org/manual/reference/method/

Если вы хотите, чтобы вернуться только определенные поля объекта, вы можете использовать

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

Если, с другой стороны, вы ищете объекты, которые содержат определенное поле, вы можете подать в суд

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

Я попытался уточнить свой вопрос с примером в исходном сообщении. Благодарю. – Carson

0

Посмотрите на db.eval:

Вы должны сделать что-то вроде:

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"); 

так фильтрация эпизодов будет на стороне сервера.

1

Match более простой:

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

Запрос:

coll.find(criteria, fields); 

Получить только определенные поля из объекта. Например:

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

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

7

Я думаю, что вы хотели это:

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"] 

Выход (кроме непечатаемых) является:

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

Если вы хотите получить избавиться от u"_id", добавить трубопровод с:

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

Я также встретил ту же проблему. То, как я это делаю, - это функция агрегата.Сначала размотайте его, а затем сопоставьте.

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

Результаты будут как

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

Это не идеально, но вы можете изменить его с помощью питона.

 Смежные вопросы

  • Нет связанных вопросов^_^