草庐IT

mongodb - 在 MongoDB 中,哪个索引会更有效率?一种是查询具有两个值的数组,还是一种使用 $or 语句?

coder 2023-11-04 原文

假设我有一个如下所示的文档:

{
  _id: ObjectId("5260ca3a1606ed3e76bf3835"),
  event_id: "20131020_NFL_SF_TEN",
  team: {
    away: "SF",
    home: "TEN"
  }
}

我想查询任何以“SF”作为客队或主队的比赛。因此,我在 team.awayteam.home 上建立了索引,并运行 $or 查询以查找所有旧金山比赛。

另一种选择:

{
  _id: ObjectId("5260ca3a1606ed3e76bf3835"),
  event_id: "20131020_NFL_SF_TEN",
  team: [
    {
      name: "SF",
      loc: "AWAY"
    },
    {
      name: "TEN",
      loc: "HOME"
    }
  ]
}

在上面的数组中,我可以在 team.name 上放置一个索引,而不是像以前那样放置两个索引。然后我会查询 team.name 以查找任何包含“SF”的游戏。

哪个查询会更有效率?谢谢!

最佳答案

我相信您会希望使用您给出的第二个示例以及 team.name 上的单个索引。

在使用 $or 运算符时,您需要了解一些特殊注意事项。引用自 documentation (有一些额外的格式):

When using indexes with $or queries, remember that each clause of an $or query will execute in parallel. These clauses can each use their own index.

db.inventory.find ( { $or: [ { price: 1.99 }, { sale: true } ] } )

For this query, you would create one index on price:db.inventory.ensureIndex({ price: 1 },
and another index on sale:db.inventory.ensureIndex({ sale: 1 } )
rather than a compound index.

考虑到您的第一个示例,为您不打算专门查询的字段编制索引没有多大意义。当你说你不介意 SF 是在客场还是主场比赛时,你会总是包括 away 查询中的home字段,因此您使用了两个索引,其中您只需要查询一个值 - SF


在这个阶段提一下似乎很合适,在考虑文档格式时,您应该始终考虑大多数查询。考虑您计划最常进行的查询并相应地构建您的文档。最好尽可能地处理 80% 的情况,而不是尝试解决所有可能性(这可能会导致整体性能更差)。


看看你的第二个例子,嵌套文档,正如你所说,你只需要使用一个索引(节省服务器上宝贵的空间)。

来自 $or docs 的更多相关引述(再次添加格式):

Also, when using the $or operator with the sort() method in a query, the query will not use the indexes on the $or fields. Consider the following query which adds a sort() method to the above query:

db.inventory.find ({ $or: [{ price: 1.99 }, { sale: true }] }).sort({item:1})

This modified query will not use the index on price nor the index on sale.

所以现在的问题是 - 您打算使用 sort() 函数吗?如果答案是肯定的,那么您应该意识到您的索引可能会变得毫无用处! :(


从中得出的结论几乎是“视情况而定!”。考虑您计划进行的查询,并根据您的使用预测考虑哪种文档结构和索引对最有利。

关于mongodb - 在 MongoDB 中,哪个索引会更有效率?一种是查询具有两个值的数组,还是一种使用 $or 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19482853/

有关mongodb - 在 MongoDB 中,哪个索引会更有效率?一种是查询具有两个值的数组,还是一种使用 $or 语句?的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  4. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  5. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  6. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  7. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  8. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  9. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

  10. ruby-on-rails - 缺失区域;使用 :region option or export region name to ENV ['AWS_REGION' ] - 2

    我知道还有其他相同的问题,但他们没有解决我的问题。我不断收到错误:Aws::Errors::MissingRegionErrorinBooksController#create,缺少区域;使用:region选项或将区域名称导出到ENV['AWS_REGION']。但是,这是我的配置开发.rb:config.paperclip_defaults={storage::s3,s3_host_name:"s3-us-west-2.amazonaws.com",s3_credentials:{bucket:ENV['AWS_BUCKET'],access_key_id:ENV['AWS_ACCE

随机推荐