与Mongoid按日期分组的最佳方法 [英] Best way to group by date with Mongoid

查看:130
本文介绍了与Mongoid按日期分组的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试按日期以不同的格式(天,月,年)对查询分组,我知道这对通常的SQL数据库来说是一个简单的查询.

I'm trying to make a query grouping by date with different formats (day, month, year), I know that it's a easy query on typically SQL databases.

您可以在此链接上查看代码: https://gist.github.com/jrdi/b3f824fa4e7531c43bfd

You can see the code on this link: https://gist.github.com/jrdi/b3f824fa4e7531c43bfd

知道我可以跑步:

> Patient.group_by('created_at', 'day')
=> [{"_id":"11/10/2013","value":{"count":3.0}}] 

在我看来,将所有这些代码组成一个简单的分组依据确实很奇怪.我错过了重要的东西吗?

In my opinion is really weird all this code for make a simple group by. Am I missing something important?

PD:我知道方法self.map和某些插值方法不是最好的方法,但是我知道我在乎Mongo的东西.

PD: I know that method self.map and some interpolation are not the best way but know I care about Mongo stuff.

推荐答案

以下是使用聚合框架按日期分组的答案.我希望你喜欢它.

Here's an answer that uses the aggregation framework to group by date. I hope that you like it.

app/model/Patient.rb

app/model/patient.rb

class Patient
  include Mongoid::Document
  field :name, type: String

  def self.group_by(field, format = 'day')
    key_op = [['year', '$year'], ['month', '$month'], ['day', '$dayOfMonth']]
    key_op = key_op.take(1 + key_op.find_index { |key, op| format == key })
    project_date_fields = Hash[*key_op.collect { |key, op| [key, {op => "$#{field}"}] }.flatten]
    group_id_fields = Hash[*key_op.collect { |key, op| [key, "$#{key}"] }.flatten]
    pipeline = [
        {"$project" => {"name" => 1, field => 1}.merge(project_date_fields)},
        {"$group" => {"_id" => group_id_fields, "count" => {"$sum" => 1}}},
        {"$sort" => {"count" => -1}}
    ]
    collection.aggregate(pipeline)
  end
end

test/unit/Patient_test.rb

test/unit/patient_test.rb

require 'test_helper'
require 'pp'

class PatientTest < ActiveSupport::TestCase
  def setup
    Patient.delete_all
  end

  test "group by date" do
    [
        {"name" => "John", "created_at" => Date.new(2012, 10, 10).mongoize},
        {"name" => "Jane", "created_at" => Date.new(2012, 10, 31).mongoize},
        {"name" => "Mary", "created_at" => Date.new(2012, 10, 31).mongoize},
        {"name" => "Mark", "created_at" => Date.new(2012, 12, 12).mongoize},
        {"name" => "Alex", "created_at" => Date.new(2013, 11, 10).mongoize},
        {"name" => "Andy", "created_at" => Date.new(2013, 10, 31).mongoize},
        {"name" => "Toni", "created_at" => Date.new(2013, 10, 31).mongoize},
        {"name" => "Cori", "created_at" => Date.new(2013, 11, 10).mongoize}
    ].each do |patient|
      Patient.create(patient)
    end
    puts "\nMongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}"
    pp Patient.group_by('created_at', 'month')
  end
end

$抽水测试

Run options:

# Running tests:

[1/1] PatientTest#test_group_by_date
Mongoid::VERSION:3.1.5
Moped::VERSION:1.5.1
[{"_id"=>{"year"=>2012, "month"=>10}, "count"=>3},
 {"_id"=>{"year"=>2013, "month"=>10}, "count"=>2},
 {"_id"=>{"year"=>2013, "month"=>11}, "count"=>2},
 {"_id"=>{"year"=>2012, "month"=>12}, "count"=>1}]
Finished tests in 0.042561s, 23.4957 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips

这篇关于与Mongoid按日期分组的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆