【问题标题】:Mongodb sub documentsMongoDB子文档
【发布时间】:2014-09-28 01:25:45
【问题描述】:

在新版本的 mongodb 中有什么方法可以:

  1. 选择一个子文档 或文档内的数组中的对象而不是检索父文档,
  2. 然后运行并再次在内存中搜索项目/子文档。

假设用户文档中有一个项目列表,其中一个项目的价格超过 50 美元。
我只想要这个项目而不是检索用户文档,然后再次搜索某个项目。

我读到它可能会在下一个版本中出现,但找不到它。 谢谢!

【问题讨论】:

    标签: mongodb select subdocument


    【解决方案1】:

    您可以使用 $elemMatch。见http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/

    所以,在你的情况下,它会像下面这样:

    db.users.insert({"items": [ {"name":"A1", "price":10}, {"name":"B1", "price":20}]}) db.users.insert({"items": [ {"name":"A2", "price":40}, {"name":"B2", "price":60}]})

    db.users.find({"items": {$elemMatch:{price:{$gt:30}}}})
    { "_id" : ObjectId("53e0c750e47ff836d16c66f4"), "items" : [ { "name" : "A2", "price" : 40 }, { "name" : "B2", "price" : 60 } ] }

    【讨论】:

    • 感谢您的回答,但这给我带来了整个集合,我仍然需要遍历它并再次找到必要的嵌入对象
    【解决方案2】:

    示例来自 mongo shell。

    1. 在文档内选择子文档或数组中的对象而不检索父文档

    对于子文档,使用projection

    > db.test.insert({ "_id" : 0, "x" : 1, "y" : 2, "embedded" : { "foo" : "bar", "counts" : [1, 2, 3, 4] } })
    > db.test.find({ "_id" : 0}, { "_id" : 0, "embedded" : 1})
    { "embedded" : { "foo" : "bar", "counts" : [ 1, 2, 3, 4 ] } }
    

    对于数组中的对象,您也可以使用投影,但只能用于从数组开头开始的切片

    > db.test.insert({ "_id" : 1, "prices" : [100, 22, 63, 234] })
    > db.test.find({ "_id" : 1}, { "_id" : 0, "prices" : { "$slice" : 2 } })
    { "prices" : [ 100, 22 ] }
    

    或使用位置运算符$匹配数组元素条件的第一个数组元素

    > db.test.find({ "prices" : { "$lt" : 100 } }, { "_id" : 0, "prices.$" : 1 })
    { "prices" : [ 22 ] }
    

    或匹配$elemMatch条件的第一个元素:

    > db.test.insert({ "_id" : 2, "users" : [{ "name" : Jill, "age" : 32 }, { "name" : Joe, "age" : 55 }, { "name" : Sam, "age" : 96 }])
    > db.test.find({"_id" : 2}, { "users" : { "$elemMatch" : { "age" : { "$gt" : 50 } } } })
    { "_id" : 2, "users" : [ { "name" : "Joe", "age" : 55 } ] }
    

    然后运行并再次在内存中搜索项目/子文档

    你这是什么意思?如果您澄清,我很乐意尝试回答。 MongoDB 根据需要将文档加载到内存中。如果一遍又一遍地查询同一组文档,它们将驻留在内存中并从内存中提供,只要整个集合适合内存(包括索引)。

    【讨论】:

    • 这个想法是不要在内存中再次查询只是为了获得相关数据并节省运行时间感谢您的详细回答,我会检查它并测试!
    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 2014-09-26
    • 2011-08-04
    • 2014-06-21
    • 2014-02-02
    • 2016-11-02
    • 2020-08-04
    • 2014-08-05
    相关资源
    最近更新 更多