【问题标题】:What's the right database for this? Mongo, SQL, Couch or something else?什么是正确的数据库? Mongo、SQL、Couch 还是其他?
【发布时间】:2012-07-22 16:48:49
【问题描述】:

假设我有一个包含 1000 万个文档的集合,看起来像这样:

{
"_id": "33393y33y63i6y3i63y63636",
"Name": "Document23",
"CreatedAt": "5/23/2006",
"Tags": ["website", "shopping", "trust"],
"Keywords": ["hair accessories", "fashion", "hair gel"],
"ContactVia": ["email", "twitter", "phone"],
"Body": "Our website is dedicated to making hair products that are..."}

我希望能够在数据库中查询任意数量的标签、关键字和 ContactVia 的 3 个属性中的任意一个,包括 0 个。我需要能够通过 ANDS(本文档包括 X 和 Y 的两个属性)或 OR(本文档包括 X OR Y 的属性)进行选择。

查询示例:

  • 给我前 10 个具有标签 website 和 购物,关键字匹配“发饰或时尚” 并带有包含“电子邮件”的contact_via。

  • 给我另外 20 个带有“网站”标签的文档或 “信任”,匹配关键字“发胶”或“发饰”。

  • 给我 50 个带有“网站”标签的文档。

我还需要按文档中的其他字段排序 (分数类型)或创建或更新日期。所以基本上有四个定期查询的“范围”。

我一开始是基于 SQL 的。然后,我搬到了 Mongo,因为它支持数组和哈希(我喜欢)。但是,它不支持使用索引的多个范围,所以我的 Mongo 数据库很慢..因为它不能使用索引并且必须扫描 1000 万个文档。

有没有更好的选择。这阻碍了将该应用程序投入生产(以及随之而来的收入)。任何关于正确数据库或替代架构的想法将不胜感激。

如果这很重要,我在 Ruby/Rails 中。

【问题讨论】:

  • 您开始在标签中遇到 *site 之类的查询.. 您可能不得不使用类似 sphinxsearch.com
  • 我不确定为什么您需要支持使用索引进行多个范围查询。如果索引用于多个查询子句,返回的结果是否仍然很大,无法在内存中高效排序?您的数据集是否足够大,以至于您无法针对不同的查询创建多个索引?
  • 标签集是否与关键字集重叠?或者它们是不重叠的集合?换句话说,一个特定的字符串可以既是关键字又是标签?
  • 我认为没有理由不能使用 SQL DB。有关替代模式,请参见此处:stackoverflow.com/questions/597016/… .. 和此处:pui.ch/phred/archives/2005/04/tags-database-schemas.html
  • 比“哪个数据库”更好的问题可能是“哪个搜索产品”。例如,请参阅Fulltext search in NoSQL databases。这取决于您是否想要 faceted searchstemmingstopwordsboolean operators 等搜索引擎功能......或者更喜欢自己创建一些更简单的东西。 Elasticsearch 似乎是一个流行的开源选项。

标签: ruby mongodb database nosql


【解决方案1】:

当需要对数组执行多个查询时,我们发现至少对我们来说最好的解决方案是使用 ElasticSearch。我们得到了这个,加上其他一些奖金。而且,我们可以减少对 Mongo 的索引要求。所以这是双赢的。

【讨论】:

    【解决方案2】:

    我的两分钱用于 MongoDB。不仅可以将您的数据表示、保存和加载为原始 Ruby 哈希,而且 Mongo 是现代且快速的,并且非常非常容易了解。以下是启动 Mongo 服务器所需要做的一切:

    mongod --dbpath /path/to/dir/w/dbs
    

    然后要获取控制台,它只是一个基本的 JavaScript 控制台,只需调用 mongo。使用它就是这么简单:

    require 'mongo'
    db = Mongo::Connection.new['somedb']
    db.stuff.find #=> []
    db.stuff.insert({id: 'abcd', name: 'Swedish Chef', says: 'Bork bork bork!'})
    db.stuff.find #=> [{id: 'abcd', name: 'Swedish Chef', says: 'Bork bork bork!'}]
    db.stuff.update({id: 'abcd', {'$set' => {says: 'Bork bork bork!!!! (Bork)!'}}})
    db.stuff.find #=> [{id: 'abcd', name: 'Swedish Chef', says: 'Bork bork bork!!!! (Bork)!'}]
    

    【讨论】:

    • 我们目前在 Mongo。但是,我们无法在没有大扫描的情况下查询它,因为您只能查询单个范围并使用索引。它不会创建具有多个范围的索引(数组、排序顺序等)。
    猜你喜欢
    • 2019-02-13
    • 2019-08-10
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多