2012-12-06 3 views
0

나는이 구조를 가지고 컬렉션의 사용자 문서가 :

{ "_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 

로그에 따르면

오토바이 : 127.0. { "$ elemMatch"=> { "date_time_created"=> { "$ gte"=> 2012 - 05-10 00:00:00 UTC, "$ lt"=> 2012-07-12 00:00:00 UTC}}}} (0.5260ms)

이렇게하면 필요한 결과를 얻습니다.

그러나, 나는 같은 기준에 따라 새로운 집계 함수와 $ 일치를 사용하려고 해요 때

오토바이 : 127.0.0.1:27017 COMMAND 데이터베이스 로그에 따르면

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

을 = db command = {: aggregate => "users", : pipeline => [{ "활동 $ ="{ "$ elemMatch"=> { "date_time_created"=> { "$ gte"=> 2012 년 5 월 10 일 (목), 2012 년 5 월 10 일, "$ lt"=> 2012 년 7 월 12 일 목요일}}}}}} (0.6049ms)

"start_date"및 "end_date"는 Ruby Date 객체이며 본질적으로 bot h 쿼리. 그러나 로그를 보면 다른 형식으로 바뀝니다. start_date.strftime ("% Y- % m- % d")과 같은 형식으로 강제 적용하려고해도 여전히 작동하지 않습니다.

집계 파이프 라인에는 다른 기능이 있지만 제거한 후에도 오류가 발생합니다.

집계 함수가 날짜와 일치하도록하려면 어떻게해야합니까?

+0

당신이하지를 여기에 $ elemMatch가 필요합니다.이 항목을 제거하고 변경 사항을 확인하십시오. $ elemMatch는 배열 요소의 두 개의 다른 속성을 비교할 때 사용합니다. 여기서는 단일 값을 테스트합니다. –

답변

6

를 사용하려고 긴장을 풀고 $ 그 이후 2를 사용한다 있도록 elemMatch를 사용하는 1 :

은 몇 가지 팁이 있습니다 당신의 질문.

첫 번째 $ 일치하는 배열 요소가 여러 개인 경우 $ addToSet을 사용하여 $ match, $ match, $ addToSet. 이것은 손실이 많은 프로세스이지만 개수 나 ID 만 필요할 경우에는 허용됩니다.

희망이 도움이됩니다. 이 같은 집계에 일치

테스트/단위/user_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 
-2

m 루비에별로 없지만, mongo 쉘을 붙여 넣을 수 있다면 도움이됩니다. 당신은 당신이 다음 테스트의 논리적 해당하는 대략적인 집계 프레임 워크를 사용 $ 일치

0

올바른 유형 : 주목

match_na = { 
    '$match': {created_at: { '$gte': (Time.now-30.days) } } 
} 

하십시오

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

이 당신이 방법을 사용한다는 의미는 : Time.zone.now를 사용하지 마십시오 (출력이 다른 형식이기 때문에). 저는 약 100 % 확신합니다.3 시간이 걸립니다.

다시이 같은 날짜 또는 시간의 형식을 확인하십시오

2017-03-07 00:36:30 +0700 

하지 않음이 :

Mon, 03 Apr 2017 00:34:14 ICT +07:00 

또는 쉬운 방법 단지 : 사용 방법 mongoize

(Date.today - 30.days).mongoize 
관련 문제