0

I have a simple dataset in a MongoDB (version 2.2.2):

{
  "_id": "527d60865593622ba17643e6",
  "siteid": "100",
  "date": 1383940800,
  "visits": 1
},
{
  "_id": "527d60865593622ba17643e7",
  "siteid": "200",
  "date": 1383940801,
  "visits": 1
},
{
  "_id": "527d60865593622ba17643e8",
  "siteid": "200",
  "date": 1383940802,
  "visits": 1
}

I have a Mongoid (version 3.0.1) collection where I'm trying to use the aggregate method:

query = {
  "$project" => { _id: 0 },
  "$match" => {"$and" => [{:date=>{"$gte"=>1383940800}}, {:date=>{"$lt"=>1384027200}}]},
  "$group" => {"_id" => "$siteid", "visits" => {"$sum" => "$visits"}},
  "$project" => { "siteid" => "$_id" }
}
result = @object.collection.aggregate(query)

The result that I get back is this:

[{"_id"=>200, "visits"=>2}, {"_id"=>100, "visits"=>1}]

What I'd like the result to be is this:

[{"siteid"=>200, "visits"=>2}, {"siteid"=>100, "visits"=>1}]

I thought the last $project operation would do this for me but it seems to be completely ignored. Any suggestions?

4

1 回答 1

0

聚合方法的参数是一个管道,它是一个哈希数组,其中每个哈希是一个阶段。您的示例查询是一个哈希值,其值为哈希值;太糟糕了,它读起来很好,但这掩盖了误用。不幸的是,Moped 以某种方式允许这种滥用,即使 mongo shell 捕获它并返回服务器错误消息“异常:管道阶段规范对象必须只包含一个字段”。我希望你喜欢下面的,我认为这是你想要的。

测试/单元/visit_test.rb

require 'test_helper'
require 'json'

class VisitTest < ActiveSupport::TestCase
  def setup
    Visit.delete_all
    puts
  end
  test "0. mongoid version" do
    puts "Mongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}"
  end
  test "project after group" do
    data = JSON.parse(<<-EOD
      [
        {"_id": "527d60865593622ba17643e6", "siteid": "100", "date": 1383940800, "visits": 1},
        {"_id": "527d60865593622ba17643e7", "siteid": "200", "date": 1383940801, "visits": 1},
        {"_id": "527d60865593622ba17643e8", "siteid": "200", "date": 1383940802, "visits": 1}
      ]
    EOD
    )
    Visit.create(data)
    assert_equal 3, Visit.count
    pipeline = [
        {"$match" => {"$and" => [{:date => {"$gte" => 1383940800}}, {:date => {"$lt" => 1384027200}}]}},
        {"$group" => {"_id" => "$siteid", "visits" => {"$sum" => "$visits"}}},
        {"$project" => {"_id" => 0, "siteid" => "$_id", "visits" => 1}}
    ]
    p Visit.collection.aggregate(pipeline)
  end
end

耙式试验

Run options:

# Running tests:

[1/2] VisitTest#test_0._mongoid_version
Mongoid::VERSION:3.1.5
Moped::VERSION:1.5.1
[2/2] VisitTest#test_project_after_group
[{"visits"=>2, "siteid"=>"200"}, {"visits"=>1, "siteid"=>"100"}]
Finished tests in 0.038172s, 52.3944 tests/s, 26.1972 assertions/s.
2 tests, 1 assertions, 0 failures, 0 errors, 0 skips
于 2013-11-13T19:57:14.483 回答