优化Mongodb文档版本控制

时间:2019-02-26 08:31:54

标签: mongodb aggregation-framework

在我的应用程序中,我需要加载大量数据并将其与特定集合中的现有文档进行比较,并对它们进行版本控制。

为了做到这一点,对于我必须插入的每个新文档,我只需使用特定键(而不是_id)进行查询并搜索最新版本,将数据分组在一起并找到最新版本。

数据示例:

{
    "_id" : ObjectId("5c73a643f9bc1c2fg4ca6ef5"),
    "data" : {
            the data
        }
    },
    "key" : {
        "value1" : "545454344",
        "value2" : "123212321",
        "value3" : "123123211"
    },
    "version" : NumberLong("1"),
}

如您所见,键由与数据相关的三个值组成,我的查询以找到最新版本如下:

db.collection.aggregate(
    {
            {
                "$sort" : {
                    "version" : NumberInt("-1")
                }
            },
            {
                "$group" : {
                    "_id" : "$key",
                    "content" : {
                        "$push" : "$data"
                    },
                    "version" : {
                        "$push" : "version"
                    },
                    "_oid" : {
                        "$push" : "$_id"
                    },
                }
            },
            {
                "$project" : {
                    "data" : {
                        "$arrayElemAt" : [
                            "$content",
                            NumberInt("0")
                        ]
                    },
                    "version" : {
                        "$arrayElemAt" : [
                            "$version",
                            NumberInt("0")
                        ]
                    },
                    "_id" : {
                        "$arrayElemAt" : [
                            "$_oid",
                            NumberInt("0")
                        ]
                    }
                }
            }
    }
)

为了提高性能(从指数级到线性级),我建立了一个包含键和版本的索引:

db.getCollection("collection").createIndex({ "key": 1, "version" : 1}) 

所以我的问题是:还有其他一些功能/策略可以优化此搜索?

注释

  • 在这些集合中,我已经使用了其他一些字段来使用match过滤数据,为简洁起见,省略了
  • 我的先决条件是加载大量数据,然后在插入之前一对一处理:如果有更好的方法来计算版本,我还可以考虑更改此内容
  • 我不确定键上的this post是否可以与查询相同。我的意思是,如果我对键和版本进行唯一索引,则可以在这对夫妇上获得唯一性,例如:
    • 收藏中没有数据:只需插入第一个版本
    • 插入新文档:尝试插入版本1,然后获取错误,对其进行迭代,这应该命中唯一索引,对吗?

2 个答案:

答案 0 :(得分:1)

我有类似的情况,这就是我解决的方法。

  • 创建一个单独的集合,其中包含Key和相应的最新版本,例如KeyVersionCollection
    • 将此集合设为“ InMemory”以加快响应速度
    • 将密钥存储在“ _id”字段中
  • 在版本集中插入文档时,说EntityVersionedCollection

这将节省聚合和排序的时间。另外,我会将最新版本保留在单独的集合-EntityCollection中。在这种情况下,对于每个实体-在EntityVersionedCollection中插入一个新版本,然后在EntityCollection中向上插入它。

在极端情况下,在获取新版本号和插入实体时使用该版本号之间的过程被中断了,您可能会看到在EntityVersionedCollection中跳过了该版本;但这应该没问题。使用时间戳跟踪插入/更新,以便将来可以用于关联/审核。

希望有帮助。

答案 1 :(得分:0)

您可以简单地将一个数组传递给mongoDB插入函数,它应该插入整个JSON有效负载,而不会出现任何内存不足的情况。

不客气