Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Mongoid聚合$match与日期对象不匹配?_Ruby On Rails_Ruby_Mongodb_Aggregation Framework_Moped - Fatal编程技术网

Ruby on rails Mongoid聚合$match与日期对象不匹配?

Ruby on rails Mongoid聚合$match与日期对象不匹配?,ruby-on-rails,ruby,mongodb,aggregation-framework,moped,Ruby On Rails,Ruby,Mongodb,Aggregation Framework,Moped,我在具有以下结构的集合中拥有用户文档: { "_id" : ObjectId( "4fb54ef46d93b33b21003951" ), "activities" : [ { "id" : ObjectId( "4fd66f9001e7fe9f03000065" ), "type" : "checkin", "date_time_created" : Date( 1339453328000 )}, { "date_time_created" :

我在具有以下结构的集合中拥有用户文档:

{ "_id" : ObjectId( "4fb54ef46d93b33b21003951" ),
  "activities" : [ 
    { "id" : ObjectId( "4fd66f9001e7fe9f03000065" ),
      "type" : "checkin",
      "date_time_created" : Date( 1339453328000 )}, 
    { "date_time_created" : Date( 1337351732000 ),
      "date_time_updated" : Date( 1337351952635 ),
      "id" : ObjectId( "4fb65e346d93b3fe77000000" )}
  ]
}
我可以根据日期轻松查询这些文档:

User.where( 
  :activities => { 
    '$elemMatch' => {
      :date_time_created => { '$gte' => start_date, '$lt' => end_date }
    }
  } 
).length
根据日志:

MOPED:127.0.0.1:27017命令数据库=db命令={:count=>“用户”,“查询=>{“活动”=>{“$elemMatch”=>{“创建日期时间”=>{“$gte”=>2012-05-10 00:00:00 UTC,$lt=>2012-07-12 00:00:00 UTC}}(0.5260ms)

我通过这种方式得到我需要的结果

但是,当我尝试使用新的聚合函数和基于相同条件的$match时:

User.collection.aggregate( [
  { "$match" => {
    :activities => {
      '$elemMatch' => {
        :date_time_created => { '$gte' => start_date, '$lt' => end_date }
      }
    }
  } }
]).length
根据日志:

MOPED:127.0.0.1:27017命令数据库=db命令={:aggregate=>“用户”,管道=>[{“$match”=>{:activities=>{“$elemMatch”=>{“创建日期时间”=>{“$gte”=>2012年5月10日星期四,$lt=>2012年7月12日星期四]}(0.6049ms)

“开始日期”和“结束日期”是Ruby日期对象,在两个查询中基本相同。但是,当我查看日志时,它们被更改为不同的格式。当我尝试使用类似start\u date.strftime(“%Y-%m-%d”)的格式强制执行时,它仍然不起作用

聚合管道中还有其他函数,但我去掉了它们,仍然得到了错误


如何使聚合函数在日期上匹配?

我对ruby不太了解,但如果您可以粘贴mongo shell,我可以提供帮助

这里有一些提示: 1.您正在使用elemMatch,因此应该使用$unwind
2.在此之后,您尝试在ruby中使用$match

m,但如果您可以粘贴mongo shell,我可以提供帮助

这里有一些提示: 1.您正在使用elemMatch,因此应该使用$unwind
2.之后,您尝试使用$match

以下测试使用聚合框架来近似查询的逻辑等价物

首先$diswind数组,$match,然后$group使用$addToSet,以防有多个匹配的数组元素。请注意,这是一个有损过程,但如果您只需要计数或ID,则这是可以接受的

希望这有帮助

测试/单元/用户_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    User.delete_all
  end

  test "user aggregate" do
    User.create(
        activities: [
          { id: Moped::BSON::ObjectId("4fd66f9001e7fe9f03000065"),
            type: "checkin",
            date_time_created: Time.at(1339453328000) },
          { date_time_created: Time.at(1337351732000),
            date_time_updated: Time.at(1337351952635),
            id: Moped::BSON::ObjectId("4fb65e346d93b3fe77000000") }
        ]
    )
    start_date = Time.at(1339453328000)
    end_date = start_date + 24*60*60
    assert_equal(1, User.where(
        :activities => {
            '$elemMatch' => {
                :date_time_created => { '$gte' => start_date, '$lt' => end_date }
            }
        }
    ).length)
    assert_equal(1, User.collection.aggregate( [
        { '$unwind' => '$activities' },
        { '$match' => { '$and' => [
            { 'activities.date_time_created' => { '$gte' => start_date } },
            { 'activities.date_time_created' => { '$lt' => end_date } }
        ] } },
        { '$group' => { '_id' => '$_id', 'activities' => { '$addToSet' =>  '$activities' } } }
    ] ).length)
  end
end
需要“测试助手”
类UserTest{
“$elemMatch”=>{
:date\u time\u created=>{'$gte'=>开始日期,$lt'=>结束日期}
}
}
)(长度)
assert_equal(1,User.collection.aggregate([
{'$unwind'=>'$activities'},
{'$match'=>{'$and'=>[
{'activities.date\u time\u created'=>{'$gte'=>start\u date},
{'activities.date\u time\u created'=>{'$lt'=>end\u date}
] } },
{'$group'=>{'$id'=>'$\U id',活动'=>{'$addToSet'=>'$activities'}}
])。长度)
结束
结束

以下测试使用聚合框架来近似查询的逻辑等价物

首先$diswind数组,$match,然后$group使用$addToSet,以防有多个匹配的数组元素。请注意,这是一个有损过程,但如果您只需要计数或ID,则这是可以接受的

希望这有帮助

测试/单元/用户_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  def setup
    User.delete_all
  end

  test "user aggregate" do
    User.create(
        activities: [
          { id: Moped::BSON::ObjectId("4fd66f9001e7fe9f03000065"),
            type: "checkin",
            date_time_created: Time.at(1339453328000) },
          { date_time_created: Time.at(1337351732000),
            date_time_updated: Time.at(1337351952635),
            id: Moped::BSON::ObjectId("4fb65e346d93b3fe77000000") }
        ]
    )
    start_date = Time.at(1339453328000)
    end_date = start_date + 24*60*60
    assert_equal(1, User.where(
        :activities => {
            '$elemMatch' => {
                :date_time_created => { '$gte' => start_date, '$lt' => end_date }
            }
        }
    ).length)
    assert_equal(1, User.collection.aggregate( [
        { '$unwind' => '$activities' },
        { '$match' => { '$and' => [
            { 'activities.date_time_created' => { '$gte' => start_date } },
            { 'activities.date_time_created' => { '$lt' => end_date } }
        ] } },
        { '$group' => { '_id' => '$_id', 'activities' => { '$addToSet' =>  '$activities' } } }
    ] ).length)
  end
end
需要“测试助手”
类UserTest{
“$elemMatch”=>{
:date\u time\u created=>{'$gte'=>开始日期,$lt'=>结束日期}
}
}
)(长度)
assert_equal(1,User.collection.aggregate([
{'$unwind'=>'$activities'},
{'$match'=>{'$and'=>[
{'activities.date\u time\u created'=>{'$gte'=>start\u date},
{'activities.date\u time\u created'=>{'$lt'=>end\u date}
] } },
{'$group'=>{'$id'=>'$\U id',活动'=>{'$addToSet'=>'$activities'}}
])。长度)
结束
结束

聚合中匹配的正确类型如下:

{:$match=>{ :created_at=>{:$gte=>2017-03-07 00:36:30 +0700}}}
2017-03-07 00:36:30 +0700
这意味着您应该使用以下方法:

match_na = {
  '$match': {created_at: { '$gte': (Time.now-30.days) } }
}
请注意:不要使用Time.zone.now(因为输出将是另一种格式)。 我非常肯定大约100%。我花了3个小时

再次:使日期或时间的格式如下:

{:$match=>{ :created_at=>{:$gte=>2017-03-07 00:36:30 +0700}}}
2017-03-07 00:36:30 +0700
不是这个:

Mon, 03 Apr 2017 00:34:14 ICT +07:00
或者简单的方法就是:使用mongoize方法

(Date.today - 30.days).mongoize

聚合中匹配的正确类型如下:

{:$match=>{ :created_at=>{:$gte=>2017-03-07 00:36:30 +0700}}}
2017-03-07 00:36:30 +0700
这意味着您应该使用以下方法:

match_na = {
  '$match': {created_at: { '$gte': (Time.now-30.days) } }
}
请注意:不要使用Time.zone.now(因为输出将是另一种格式)。 我非常肯定大约100%。我花了3个小时

再次:使日期或时间的格式如下:

{:$match=>{ :created_at=>{:$gte=>2017-03-07 00:36:30 +0700}}}
2017-03-07 00:36:30 +0700
不是这个:

Mon, 03 Apr 2017 00:34:14 ICT +07:00
或者简单的方法就是:使用mongoize方法

(Date.today - 30.days).mongoize
我发现,这对我很有帮助。下面是一个重要的代码示例-相比之下似乎非常简单:

Stat.collection.aggregate({
  '$match' => {
    '$and' => [
      { 'day' => { '$gte' => from.to_date.mongoize } },
      { 'day' => { '$lte' => to.to_date.mongoize } }
    ]
  },
})
向作者致敬

我发现,这对我很有帮助。下面是一个重要的代码示例-相比之下似乎非常简单:

Stat.collection.aggregate({
  '$match' => {
    '$and' => [
      { 'day' => { '$gte' => from.to_date.mongoize } },
      { 'day' => { '$lte' => to.to_date.mongoize } }
    ]
  },
})

向作者致敬

你不需要$elemMatch在这里-你可以删除它,看看这是否改变了什么$elemMatch用于比较两个d