如何在嵌套数组中查询。(使用pymongo)

时间:2011-09-11 16:38:28

标签: arrays mongodb pymongo

我是mongodb的新蜜蜂。 我做了一个这样的嵌套数组文档。

data = {
    "title": "mongo community",
    "description": "I am a new bee",
    "topics": [{
        "title": "how to find object in array",
        "comments": [{
            "description": "desc1"
        }]
    },
    {
        "title": "the case to use ensureIndex",
        "comments": [{
            "description": "before query"
        },
        {
            "description": "If you want"
        }
        ]
    }
    ]
}

之后,把它放在“社区”中 db.community.insert(数据)

所以,我想积累“评论”哪个主题标题是“如何在数组中查找对象” 然后我试过了,

  
    

data = db.community.find_one({“title”:“mongo community”,“topics.title”:“如何在数组中查找对象”})

  

结果是

>>> print data
{
    u 'topics': [{
        u 'comments': [{
            u 'description': u 'desc1'
        }],
        u 'title': u 'how to find object in array'
    },
    {
        u 'comments': [{
            u 'description': u 'before query'
        },
        {
            u 'description': u 'If you want'
        }],
        u 'title': u 'the case to use ensureIndex'
    }],
    u '_id': ObjectId('4e6ce188d4baa71250000002'),
    u 'description': u 'I am a new bee',
    u 'title': u 'mongo community'
}

我不需要主题“使用ensureIndex的情况”

你能不能给我任何建议。

THX。

2 个答案:

答案 0 :(得分:3)

看起来您将主题作为数组嵌入到单个文档中。您应该尽量避免经常从MongoDB返回部分文档。你可以使用find方法的“fields”参数来完成它,但如果你经常这样做,它就不是很容易使用。

因此,要解决此问题,您可以尝试将每个主题作为单独的文档。我觉得这对你来说也会更容易。如果您想保存论坛的“社区”信息,请将其放在单独的集合中。例如,您可以在monbodb shell中使用以下内容:

// ad a forum:
var forum = { 
                title:"mongo community",
                description:"I am a new bee"
            };
db.forums.save(forum);

// add first topic:
var topic = {
                title: "how to find object in array",
                comments: [ {description:"desc1"} ],
                forum:"mongo community"
            };
db.topics.save(topic);

// add second topic:
var topic = {
                title: "the case to use ensureIndex",
                comments: [ 
                    {description:"before query"},
                    {description:"If you want"}
                ],
                forum:"mongo community"
            };
db.topics.save(topic);

print("All topics:");
printjson(db.topics.find().toArray());


print("just the 'how to find object in array' topic:")
printjson(db.topics.find({title:"how to find object in array"}).toArray());

另外,请参阅有关MongoDB中架构设计的文档Trees In MongoDB。它恰好使用了与您正在使用的类似的模式,并针对更高级的用例进行了扩展。

答案 1 :(得分:0)

MongoDB对文档进行操作,即顶级文档(您saveupdateinsertfindfind_one上的内容)。 Mongo的查询语言允许您在嵌入对象中进行搜索,但始终会返回,更新或操作这些顶级文档中的一个(或多个)。

MongoDB通常被称为“无模式”,但更像是“(有)灵活模式”或“(有)每个文档模式”将是更准确的描述。在这种情况下,您的架构设计(直接嵌入社区中的主题)不适用于此特定查询。但是,此架构可能更有效地支持其他查询,例如在单个查询中列出社区内的主题。您可能希望考虑要进行的查询并相应地重新设计架构。

关于MongoDB限制的一些注释:

  1. 始终返回顶级文档(可选择只包含一部分字段,如@scott所述 - 请参阅此主题的the mongodb docs
  2. 每个文档限制为16兆字节的数据(从版本1.8+开始),因此如果社区有很长的主题列表,这个模式将无法正常工作
  3. 有关架构设计的帮助,请参阅the mongodb docs on schema designKyle Banker's video "Schema Design Basics"Eliot Horowitz's video "Schema Design at Scale"以获取介绍,提示和注意事项。