我有一个特定的数据操作要求,我已经解决了如何在SQL Server和PostgreSQL中做的事情。但是,我对速度不太满意,所以我正在调查MongoDB。
描述查询的最佳方法如下。描绘美国的分层数据:国家,州,县,市。假设一个特定的供应商可以为整个加州服务。另一个可能只服务于洛杉矶。可能有数十万个供应商,他们都可以从这个层次结构中的某些点进行服务。我并没有把它与Geo混淆 - 我用它来说明需要。
使用递归查询,可以非常简单地获得可以为特定用户提供服务的所有供应商的列表。如果他在加利福尼亚州洛杉矶的帕萨迪纳说,我们会走上层次结构以获取适用的ID,然后再回头查找供应商。
我知道这可以优化。同样,这只是一个简单的查询示例。
我知道MongoDB是一个文档存储。这非常适合我的其他需求。问题是它对我描述的查询类型有多适合? (我知道它没有连接 - 这些是模拟的)。
我知道这是“一段字符串多长时间”的问题。我只是想知道是否有任何人有使用MongoDB做这种事情的经验。从0开始测试可能需要一段时间,如果MongoDB不适合这个,我希望节省时间。
示例
本地电影商店“A”可以在斯普林菲尔德提供Blu-Rays。具有全州分布的连锁店“B”可以向所有IL提供Blu-Rays。按需下载商店“C”可以供应给所有美国人。
如果我们想要获得伊利诺伊州斯普林菲尔德的所有适用电影供应商,那么答案将是[A,B,C]。
换句话说,在层次结构上有许多不同级别的供应商。
答案 0 :(得分:8)
我意识到这个问题是在近一年前提出来的,但从那时起MongoDB就有了这个问题的官方支持解决方案,我只是使用了他们的解决方案。请参阅此处的文档:http://www.mongodb.org/display/DOCS/Trees+in+MongoDB
与您的问题最相关的部分位于页面的“部分路径”部分下。
虽然嵌入祖先数据可能会有点沉重;这种方法是解决MongoDB问题的最合适方法。我到目前为止遇到的唯一陷阱是,如果你将所有这些存储在一个文档中,那么在处理足够的数据时,你可以达到16MB的文档大小限制(尽管,我只能看到这种情况发生,如果你使用这种结构来跟踪用户推荐[可能达到数百万]而不是美国城市[根据最新的美国人口普查,这超过26,000]。
<强>参考文献:强>
答案 1 :(得分:2)
请注意,谷歌小组也提出了这个问题。有关该问题,请参阅http://groups.google.com/group/mongodb-user/browse_thread/thread/5cd5edd549813148。
一种选择是使用数组键。您可以将层次结构存储为 值数组(例如['US','CA','洛杉矶'])。然后你可以 根据该数组键中的各个元素查询记录 例如: 首先,使用表示的数组值存储一些文档 等级
> db.hierarchical.save({ location: ['US','CA','LA'], name: 'foo'} )
> db.hierarchical.save({ location: ['US','CA','SF'], name: 'bar'} )
> db.hierarchical.save({ location: ['US','MA','BOS'], name: 'baz'} )
确保我们在位置字段上有索引,以便我们执行 快速查询其值
> db.hierarchical.ensureIndex({'location':1})
查找加利福尼亚州的所有记录
> db.hierarchical.find({location: 'CA'})
{ "_id" : ObjectId("4d9f69cbf88aea89d1492c55"), "location" : [ "US", "CA", "LA" ], "name" : "foo" }
{ "_id" : ObjectId("4d9f69dcf88aea89d1492c56"), "location" : [ "US", "CA", "SF" ], "name" : "bar" }
查找马萨诸塞州的所有记录
> db.hierarchical.find({location: 'MA'})
{ "_id" : ObjectId("4d9f6a21f88aea89d1492c5a"), "location" : [ "US", "MA", "BOS" ], "name" : "baz" }
查找美国境内的所有记录
> db.hierarchical.find({location: 'US'})
{ "_id" : ObjectId("4d9f69cbf88aea89d1492c55"), "location" : [ "US", "CA", "LA" ], "name" : "foo" }
{ "_id" : ObjectId("4d9f69dcf88aea89d1492c56"), "location" : [ "US", "CA", "SF" ], "name" : "bar" }
{ "_id" : ObjectId("4d9f6a21f88aea89d1492c5a"), "location" : [ "US", "MA", "BOS" ], "name" : "baz" }
请注意,在此模型中,您需要在数组中使用值 独特。例如,如果你有不同状态的'springfield', 那么你需要做一些额外的工作来区分。
> db.hierarchical.save({location:['US','MA','Springfield'], name: 'one' })
> db.hierarchical.save({location:['US','IL','Springfield'], name: 'two' })
> db.hierarchical.find({location: 'Springfield'})
{ "_id" : ObjectId("4d9f6b7cf88aea89d1492c5b"), "location" : [ "US", "MA", "Springfield"], "name" : "one" }
{ "_id" : ObjectId("4d9f6b86f88aea89d1492c5c"), "location" : [ "US", "IL", "Springfield"], "name" : "two" }
您可以通过使用$ all运算符并指定更多来解决此问题 层次结构的级别。例如:
> db.hierarchical.find({location: { $all : ['US','MA','Springfield']} })
{ "_id" : ObjectId("4d9f6b7cf88aea89d1492c5b"), "location" : [ "US", "MA", "Springfield"], "name" : "one" }
> db.hierarchical.find({location: { $all : ['US','IL','Springfield']} })
{ "_id" : ObjectId("4d9f6b86f88aea89d1492c5c"), "location" : [ "US", "IL", "Springfield"], "name" : "two" }