【问题标题】:How do I execute this query using the aggregation framework in MongoDB?如何使用 MongoDB 中的聚合框架执行此查询?
【发布时间】:2012-07-25 01:06:33
【问题描述】:

我正在尝试返回大于 12 的 visits minute

我的数据结构是这样的:

{ "_id" : "20120723/foobar/song/custom-cred",
  "live_daily_count" : 4,
  "metacontent" : { "date" : "20120723",
    "live_daily_statable_slug" : "custom-cred",
    "live_daily_statable_title" : "custom cred",
    "live_daily_statable_type" : "Song",
    "url" : "foobar/songs/custom-cred",
    "user_slug" : "foobar" },
  "visits" : [
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/foobar/songs/no-title-with-space",
      "minute" : 12,
      "token_id" : "134300236111rcbmbmvv" },
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/foobar/songs/no-title-with-space",
      "minute" : 13,
      "token_id" : "134300242111pjvkjjkf" },
    { "country_name" : "UK",
      "iso_two_letter_country_code" : "UK",
      "referer" : "http://localhost:3000/foobar/songs/no-title-with-space",
      "minute" : 13,
      "token_id" : "134300243511udbnqldm" }
  ]
}

我正在使用 Mongodb Ruby 驱动程序。我尝试了以下方法:

conn = Mongo::Connection.new
db   = conn['foobar_development']
cmd = {
  aggregate: 'live_daily_stats',
  pipeline: [
    { '$match' => { :_id => "20120723/foobar/song/custom-cred" } },
    { '$project' => {
      :visits => 1,
    } },
    { '$unwind' => '$visits' },
    # { '$group' => {
    #   :_id => '$_id'
    # } },
  ]
}

res = db.command(cmd)['result']

它现在返回:

[
    [0] {
           "_id" => "20120723/foobar/song/custom-cred",
        "visits" => {
                                          "country_name" => "UK",
                           "iso_two_letter_country_code" => "UK",
                                               "referer" => "http://localhost:3000/foobar/songs/custom-cred",
                                                "minute" => 12,
                                              "token_id" => "134300236111rcbmbmvv"
        }
    },
    [1] {
           "_id" => "20120723/foobar/song/custom-cred",
        "visits" => {
                                          "country_name" => "UK",
                           "iso_two_letter_country_code" => "UK",
                                        "follower_class" => "non_follower",
                                               "referer" => "http://localhost:3000/foobar/songs/custom-cred",
                                                "minute" => 13,
                                              "token_id" => "134300242111pjvkjjkf"
        }
    },
    [2] {
           "_id" => "20120723/foobar/song/custom-cred",
        "visits" => {
                                          "country_name" => "UK",
                           "iso_two_letter_country_code" => "UK",
                                        "follower_class" => "non_follower",
                                               "referer" => "http://localhost:3000/foobar/songs/custom-cred",
                                                "minute" => 13,
                                              "token_id" => "134300243511udbnqldm"
        }
    }
]

如何确保结果仅返回 visitsminute 大于 12?任何帮助将不胜感激。

【问题讨论】:

  • 您不想 $unwind 字段 $visits(什么是 $data?)。而且我认为 $unwind 仅适用于数组(您的访问不是)。
  • 查看我的编辑,$unwind。仍然是相同的结果[]。其次,我应该改变我的数据结构,使它使用数组而不是散列吗?有什么方法可以让它使用哈希而不是数组?我使用哈希没有特别的原因。只是个人喜好
  • 您是否考虑过为访问日志使用单独的集合?这将使这个特定的查询变得微不足道(当然,我们不知道您的其他查询)。
  • 像引用或嵌入文档那样分离集合?
  • 引用,未嵌入,是的。 “访问”中的每个条目都将包含父文档的 ID。这消除了对每个文档可以存储的最大访问次数的限制,并且更新速度也更快。 (缺点是无法进行“连接类型”查询)。

标签: ruby-on-rails ruby ruby-on-rails-3 mongodb


【解决方案1】:

您在开始时使用的 $match 管道元素可以多次使用,包括在您的 $unwind 步骤之后。

一旦 $unwind 将您的访问数组元素拆分为自己的文档,您就可以将 {$match:{"visits.minute":{$gt:12}}} 添加到管道的末尾,并且应该只留下访问次数你想要的。

【讨论】:

    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 2014-05-11
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 2019-11-18
    • 2017-01-25
    • 1970-01-01
    相关资源
    最近更新 更多