특정 날짜에 MongoDB / Mongoose 쿼리?


141

특정 날짜를 쿼리 할 수 ​​있습니까?

나는 우리가 범위을 위해 할 수있는 몽고 요리 책에있는 날짜 범위에 대한 쿼리 처럼한다 :

db.posts.find({"created_on": {"$gte": start, "$lt": end}})

그러나 특정 날짜에 가능합니까? 작동하지 않습니다.

db.posts.find({"created_on": new Date(2012, 7, 14) })

답변:


212

DB에 저장 한 날짜가 시간이없는 경우 (단지 년, 월, 일) 작동합니다.

저장 한 날짜 new Date()가 시간 구성 요소를 포함하여 일 가능성이 있습니다 . 해당 시간을 쿼리하려면 하루의 모든 순간을 포함하는 날짜 범위를 만들어야합니다.

db.posts.find( //query today up to tonight
  {"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

29
Date () 함수에서 월 인수는 1이 아니라 0부터 계산을 시작한다는 것을 기억하십시오. 반면에, 일은 1부터 계산을 시작합니다 ... 세부 사항
Mark Stosberg

두 가지를 모두 하드 코드하는 대신 다음 날짜를 얻으려면 _ 1 일을하는 것이 낫지 않습니까?
raju

2
>> "date": ISODate ( "2016-01-04T14 : 07 : 17.496Z")
santhosh

월 및 날짜 전환이 없습니다. 날짜 형식은 yyyy, dd, MM
thethakuri

123

... 5 년 후, 대신 date-fn을 사용하는 것이 좋습니다.

import endOfDayfrom 'date-fns/endOfDay'
import startOfDay from 'date-fns/startOfDay'

MyModel.find({
  createdAt: {
    $gte: startOfDay(new Date()),
    $lte: endOfDay(new Date())
  }
})

Moment.js를 사용하는 사람들 에게는

const moment = require('moment')

const today = moment().startOf('day')

MyModel.find({
  createdAt: {
    $gte: today.toDate(),
    $lte: moment(today).endOf('day').toDate()
  }
})

중요 : 모든 순간은 변경 가능합니다 !

tomorrow = today.add(1, 'days')또한 변이되기 때문에 작동하지 않습니다 today. 호출 moment(today)은 암시 적으로 복제하여 해당 문제를 해결합니다 today.


13
.startOf('day').hours (0) .minutes (0) .seconds (0) 대신 사용 하는 것이 좋습니다 . 따라서 첫 번째 줄은 다음과 같습니다.var today = moment().startOf('day')
Jim Geurts

2
우리가 moment(today)객체를 복제하는데 사용한다면 , 또 다른 해결책은 다음과 같습니다.var tomorrow = today.clone().add(1, 'days')
johntellsall

1
@johntellsall 암시적이고 동일한 결과이지만 명시적인 읽기가 아닌 명시적인 복제!
Pier-Luc Gendreau

1
또한, 나는에 대해 다음을 제안 할 수있다 $lt: moment(today).endOf('day'). 다음날의 실제 결과가 포함되지 않도록합니다.
greduan

1
나를 moment(today).endOf('day')위해 같은 날에 시간을 준다 : 23:59:59.999. 따라서 실제로 사용하는 것이 더 정확 해 보입니다 $lte. 그렇지 않으면 해당 특정 시간의 객체가 무시됩니다.
leonprou

11

예, Date 객체는 날짜와 시간을 구성하므로 날짜 값만 비교하면 작동하지 않습니다.

$ where 연산자를 사용하여 Javascript 부울 표현식으로 더 복잡한 조건을 표현할 수 있습니다. :)

db.posts.find({ '$where': 'this.created_on.toJSON().slice(0, 10) == "2012-07-14"' })

created_on날짜 시간 필드이며 2012-07-14지정된 날짜입니다.

날짜는 정확히 YYYY-MM-DD 형식 이어야 합니다.

참고 :$where 약간만 사용하면 성능에 영향을 미칩니다.


10

시도해 보셨습니까?

db.posts.find({"created_on": {"$gte": new Date(2012, 7, 14), "$lt": new Date(2012, 7, 15)}})

문제는 Mongo에서 날짜가 타임 스탬프로 저장된다는 것입니다. 따라서 날짜를 맞추려면 타임 스탬프와 일치하도록 요청하십시오. 귀하의 경우에는 하루 종일 일치하려고한다고 생각합니다 (예 : 특정 날짜의 00:00 ~ 23:59). 날짜가 시간없이 저장되면 괜찮을 것입니다. 그렇지 않으면, gte가 작동하지 않으면 날짜를 같은 날의 시간 범위 (예 : start = 00 : 00, end = 23 : 59)로 지정하십시오.

비슷한 질문


1
여기에는 지정된 날짜보다 어린 모든 요소가 포함되며 OP가 원치 않는 것입니다. 다른 답변과 같이 "lt"옵션을 추가하십시오.
BenSower

나는 당신이 그것을 $gte대신 한다면 gte더 좋을 것이라고 생각합니다 .
jack blank

이것은 이미 위에서보다 정확하게 대답되었지만 내 대답이 꺼져 있다는 것을 알았 기 때문에 질문에 맞도록 업데이트했습니다. 이봐, 4 년이 지났어. lol
Michael D Johnson

6

API 메소드에 대해 다음 방법을 사용하여 특정 날짜의 결과를 얻을 수 있습니다.

# [HTTP GET]
getMeals: (req, res) ->
  options = {}
  # eg. api/v1/meals?date=Tue+Jan+13+2015+00%3A00%3A00+GMT%2B0100+(CET)
  if req.query.date?
    date = new Date req.query.date
    date.setHours 0, 0, 0, 0
    endDate = new Date date
    endDate.setHours 23, 59, 59, 59
    options.date =
      $lt: endDate
      $gte: date

  Meal.find options, (err, meals) ->
      if err or not meals
        handleError err, meals, res
      else
        res.json createJSON meals, null, 'meals'

1

데이터베이스에 중복 된 데이터와 관련된 문제가있었습니다. 날짜 필드에 여러 값이 있어야하는데 1을 의미했습니다. 문제를 해결하기위한 방법을 추가 할 것이라고 생각했습니다.

숫자 "value"필드와 날짜 "date"필드가있는 "data"라는 컬렉션이 있습니다. 우리는 dem 등원이라고 생각한 프로세스를 가지고 있었지만 두 번째 실행에서 하루에 2 x 값을 추가했습니다.

{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}

우리는 두 개의 레코드 중 하나만 필요하므로 DB를 정리하기 위해 자바 스크립트를 사용해야했습니다. 우리의 초기 접근 방식은 결과를 반복하고 오전 6시에서 오전 11시 사이의 모든 필드를 제거하는 것이었지만 (모두 중복은 아침에 있었음) 구현하는 동안 변경되었습니다. 이를 수정하는 데 사용되는 스크립트는 다음과 같습니다.

var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
    var datum = data.next();
    var rdate = datum.date;
    // instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
    if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
       if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
           print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
       }
       else {
           print("Removing " + datum._id);
           db.data.remove({ "_id": datum._id});
       }
    }
    else {
       found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
    }
}

그런 다음 그것을 실행 mongo thedatabase fixer_script.js

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.