【问题标题】:mongodb indexing subarray valuesmongodb索引子数组值
【发布时间】:2013-08-16 13:16:44
【问题描述】:

如果我在 mongodb 中有这样的数组结构:

"field":
[
     [10,20]  //specified length per array
     [25,40]
     [60,90]
     ...and so on, with various size per document
]

我怎样才能索引这个子数组? 我试图索引: db.ensureIndex({"field.$.0":1}); //和 {"field.$.1":1}

但是在文档中搜索仍然很慢。

我也试过这个解决方案: MongoDB, array of arrays index 但是

db.ensureIndex("{field:[{"a":1}]}"); //and "{field:[{"b":1}]}" 

如果 a 命名子数组索引 a 和 b,则此 sintax 会抛出“bad index key pattern”异常。

【问题讨论】:

  • 您的查询要求是什么?

标签: mongodb indexing mongodb-query


【解决方案1】:

你能解释更多你想要做什么吗?第一个模式设计不是很好;你有一堆数组,除了使用可能非常慢的数组运算符之外,你真的无法解决。

您的第二个想法似乎步入正轨,但是您的语法有点偏离。如果您可以插入文档而不是子数组,您会发现架构更容易处理,并且您可以对每个文档中的两个值进行索引,如下所示:

> db.test.insert({field: [{a:1, b:2}, {a:3, b:4}]})
> db.test.ensureIndex({"field.a":1})
> db.test.ensureIndex({"field.b":1})
> db.test.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "test.test",
                "name" : "_id_"
        },
        {
                "v" : 1,
                "key" : {
                        "field.a" : 1
                },
                "ns" : "test.test",
                "name" : "field.a_1"
        },
        {
                "v" : 1,
                "key" : {
                        "field.b" : 1
                },
                "ns" : "test.test",
                "name" : "field.b_1"
        }
]
> db.test.find({"field.a": 3})
{ "_id" : ObjectId("520e2ec749177daf439a2ff6"), "field" : [ { "a" : 1, "b" : 2 }, { "a" : 3, "b" : 4 } ] }

您可以运行一个解释来查看确实正在使用该索引(请参阅光标行)

> db.test.find({"field.a": 3}).explain()
{
        "cursor" : "BtreeCursor field.a_1",
        "isMultiKey" : true,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "indexBounds" : {
                "field.a" : [
                        [
                                3,
                                3
                        ]
                ]
        },
        "server" : "xxxxx-PC:27017"
}

【讨论】:

  • 所以“我尝试查找范围为:...”的文档,但是有多个范围,10 到 20、25 到 40 等等,我不知道将插入许多范围,因此我(认为)需要使用一个字段,该字段是一个包含一些 2 元素数组的数组,其中包含最小值和最大值,我需要快速查找。(而且我是新手noSQL)
  • 如果我理解你的问题而不是做 db.test.find({"field.a" : 3}) 你可以做 db.test.find({field : {$elemMatch: { a : {$lte: 3}, b: {$gte: 3} } } })。这将为您找到该字段具有包含值 3 的范围的文档。如果您运行解释,您将看到索引按预期使用。
  • 是的,我想找到它(我也可以找到它)但是太慢了,我不知道如何索引这些字段。我在某处看到:field.$.0 field.$.1 是解决方案,但它不起作用。
  • 查看我上面评论中的代码并尝试一下 - db.test.find({field : {$elemMatch: { a: {$lte: 3}, b: {$gte: 3 } } } })。将您的索引设置为 db.ensureIndex({"field.a":1})。如果你运行一个解释,你会看到它使用索引。如果它仍然太慢,那么您需要重新检查您的架构,因为如果不更改某些内容,您不会比索引查询更快。
  • 这个解决方案太慢了,我真的需要修改架构,谢谢帮助
猜你喜欢
  • 2017-01-11
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多