我在一个集合中有一个超过1B文档的生产mongo数据库,它跨越多个服务器在_id上分片。我正在尝试将此集合中最近更新的记录复制到Red Shift。
分片键:
db.sample_collection.ensureIndex({_ id:“hashed”})
sh.shardCollection(“sample_collection.sample_object”,{_ id:“hashed”})
示例'sample_object'文档
{
"_id" : ObjectId("527a6c9226d6b7770ab05345"),
"p": ISODate("2013-10-27T14:30:18.000Z"),
"a" : {
"ln" : "Doe",
"id" : NumberLong(3),
"fn" : "John",
},
"co" : {
"ct" : 2,
"it" : [
{'t': 'loreum', 'u' : NumberLong(300), 'd': ISODate("2013-10-28T14:30:18.000Z")},
{'t': 'loreum', 'u' : NumberLong(400), 'd': ISODate("2013-10-29T14:30:18.000Z")},
..]
},
"li" : {
"ct" : 2,
"it" : [
{'u' : NumberLong(500), 'd': ISODate("2013-10-30T14:30:18.000Z")},
{'u' : NumberLong(501), 'd': ISODate("2013-10-29T14:30:18.000Z")},
..]
},
}
选项#1:
我正在分析这些数据,我需要查询一段时间内“更新”的文档。 即,我想返回所有已经过p(已发布)的对象或者在“2014-07-01”和“2014-07-03”之间添加的li.it(item)或co.it(item)。< / p>
这样做最有效的方法是什么?
选项#2:
我正在评估的另一个选项是我是否要添加一个带有更新日期的'u'属性来说明文档何时更新 (即,li或co项目已添加)
如果我对流程进行了更改以确保新文档具有此属性,我将如何遍历现有文档并追溯添加此文档?
过滤'u'会比选项1更高效吗?我正在将此选项视为使用来自mongoexport的COPY FROM JSON
答案 0 :(得分:1)
对此进行索引并不是一个很好的选择,因为看起来您理想情况下需要一个包含p
(日期)和两个日期数组(lt.it
和{{1}的复合索引}})。复合索引最多只能包含one array field。即使您可以这样做,根据建议的日期数量,索引也会非常大,查询将涉及检查多个字段以推断上次更新日期。
添加索引co.it
(最新更新日期)绝对是一种更好的方法,可以进行简单且高效的查询。
如果我对流程进行了更改以确保新文档具有此属性,我将如何遍历现有文档并追溯添加此文档?
您可以使用$exists
operator查找尚未设置此字段的文档。
详细说明Neil的评论:散列的分片键为您提供了良好的写入分发,代价是能够进行范围查询(所有查询都变为分散 - 聚集)。如果您的常见查询是基于日期的范围(并且您关注性能),那么您可能chose a more appropriate shard key支持这些查询。但是,由于分片键是immutable,并且您想查询&#34;更新&#34;日期,它听起来不像是更改分片键有助于你的用例。