【问题标题】:MongoDB Indexes for dynamic sub-fields动态子字段的 MongoDB 索引
【发布时间】:2019-02-23 23:57:36
【问题描述】:

MongoDB 3.0.2。文档示例:

{ "_id" : NumberLong(1), Categories : { "123" : { "Shows" : NumberLong(7), "Clicks" : NumberLong(0) }, "221" : { "Shows" : NumberLong(33), "Clicks" : NumberLong(12) } } }
{ "_id" : NumberLong(2), Categories : { "221" : { "Shows" : NumberLong(33), "Clicks" : NumberLong(12) } } }
{ "_id" : NumberLong(3), Categories : { "123" : { "Shows" : NumberLong(8), "Clicks" : NumberLong(1) } } }
{ "_id" : NumberLong(4), Categories : { "99" : { "Shows" : NumberLong(144), "Clicks" : NumberLong(39) }, "221" : { "Shows" : NumberLong(52), "Clicks" : NumberLong(2) } } }
{ "_id" : NumberLong(5), Categories : { "95" : { "Shows" : NumberLong(18), "Clicks" : NumberLong(3) } } }
{ "_id" : NumberLong(6), Categories : { "123" : { "Shows" : NumberLong(89), "Clicks" : NumberLong(69) } } }

在我的例子中,像“123”、“221”、“99”、“95”这样的字符串值是一些类别的ID。我只需要使用类别 ID 按 Shows 进行排序:

db.myCollection.find().sort( Categories."1".Shows : -1 )
db.myCollection.find().sort( Categories."95".Shows : 1 )
db.myCollection.find().sort( Categories."123".Shows : 1 )
db.myCollection.find().sort( Categories."221".Shows : -1 )

但是这个类别的数量大约是 250+。我无法为每个设置索引,例如:

db.myCollection.createIndex( { Categories."[1..250]".Shows : 1 } );

因为 cat id 超过 64 个(MongoDB 限制),并且这个类别可以添加和删除到只是一些记录并且这个过程是动态的。

没有索引我得到:

带有消息的未捕获异常“MongoCursorException” 'localhost:27017:执行程序错误:溢出排序阶段缓冲数据 33554646 字节的使用量超过了 33554432 字节的内部限制..

有人可以为这种情况提供解决方案吗?

【问题讨论】:

    标签: mongodb exception indexing multikey


    【解决方案1】:

    我认为您无法使用当前的文档设计解决此问题。

    您可能希望以不同的方式为您的类别建模,例如使用这样的类别数组:

    {
        "_id" : 1,
        "Categories": [
            {
                "CategoryId": "123",
                "Details": {
                    "Shows": 7,
                    "Clicks": 0
            }, {
                "CategoryId": "221",
                "Details": {
                   "Shows": 33,
                   "Clicks": 12
                }
            }
        ]
    }
    

    在这种情况下,您可以轻松添加单个索引db.collection.createIndex({"Categories.Details.Shows": 1})

    【讨论】:

    • 但在这种情况下,我仍然无法为“Shows”字段添加索引。我需要按每个类别的“节目”排序。对于您的设计案例 db.myCollection.find({"Categories.CategoryId":"123"}).sort("Categories.Details.Shows" : -1 ) - "Shows" 未编入索引。
    • @DoanldF 对不起,这是我的错误。我弄错了字段。但是,是的,通过这种设计,您也可以在 Shows 上添加索引。
    【解决方案2】:
    使用稍微修改过的 dnickless 架构,如下所示:
    {
        “_id”:1,
        “类别”:[
            {
                "CategoryId": "123",
                “节目”:7,
                “点击次数”:0
            },
            {
                "CategoryId": "221",
                “节目”:33,
                “点击次数”:12
            }
        ]
    }
    
    然后,您可以为节目创建索引。
    db.collection.createIndex({"Categories.Shows": 1})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-20
      • 2011-08-28
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-09
      相关资源
      最近更新 更多