[MONGODB] MongoDB를이 - 시간의 시간 범위 사이에 쿼리
MONGODBMongoDB를이 - 시간의 시간 범위 사이에 쿼리
나는이 같은 저장된 위치 데이터와 설정 MongoDB의 데이터 저장소를 가지고 :
{
"_id" : ObjectId("51d3e161ce87bb000792dc8d"),
"datetime_recorded" : ISODate("2013-07-03T05:35:13Z"),
"loc" : {
"coordinates" : [
0.297716,
18.050614
],
"type" : "Point"
},
"vid" : "11111-22222-33333-44444"
}
나는 날짜 범위의 예와 유사하지만, 대신 시간 범위에 대한 쿼리를 수행 할 수 있도록하고 싶습니다. 즉 (도 1200 1600 24시 시간에 행해질 수있다) 자정 오후 4시 사이에 기록 된 모든 포인트를 검색.
EG
포인트 :
쿼리
db.points.find({'datetime_recorded': {
$gte: Date(1200 hours),
$lt: Date(1600 hours)}
});
첫 번째와 마지막 포인트를 얻을 것입니다.
이것이 가능한가? 아니면 내가 매일을 위해 그것을 할 것?
해결법
-
==============================
1.음,이 문제를 해결하는 가장 좋은 방법은 별도로뿐만 아니라 분을 저장하는 것입니다. 이들은 매우 빠르게 될 수 없습니다 있지만 그러나 당신은, 집계 프레임 워크와이 주위를 얻을 수 있습니다 :
음,이 문제를 해결하는 가장 좋은 방법은 별도로뿐만 아니라 분을 저장하는 것입니다. 이들은 매우 빠르게 될 수 없습니다 있지만 그러나 당신은, 집계 프레임 워크와이 주위를 얻을 수 있습니다 :
db.so.aggregate( [ { $project: { loc: 1, vid: 1, datetime_recorded: 1, minutes: { $add: [ { $multiply: [ { $hour: '$datetime_recorded' }, 60 ] }, { $minute: '$datetime_recorded' } ] } } }, { $match: { 'minutes' : { $gte : 12 * 60, $lt : 16 * 60 } } } ] );
$ 일치 : 첫 번째 단계 $ 프로젝트에서, 우리는 시간에 우리는 다음 두 번째 단계에 대해 일치 * 60 + 분에서 분을 계산합니다.
-
==============================
2.난 당신이 통합 프레임 워크로 할 수있는 큰 일이있다하더라도,이 정말 이러한 유형의 쿼리를 수행 할 수있는 최적의 방법이 아니라고에서 다른 답변에 동의하기 때문에 답변을 추가.
난 당신이 통합 프레임 워크로 할 수있는 큰 일이있다하더라도,이 정말 이러한 유형의 쿼리를 수행 할 수있는 최적의 방법이 아니라고에서 다른 답변에 동의하기 때문에 답변을 추가.
당신의 식별 된 응용 프로그램 사용 패턴을 사용하면 "날짜"부분을보고 싶어하지 않고 "시간"또는 하루 중 다른 시간에 대한 쿼리에 의존하는 경우, 당신은이 문서에서 숫자 값으로 훨씬 더 저장 꺼져 있습니다. "일의 시작부터 밀리 초"와 같은 뭔가에 대한 BSON 날짜 등 다양한 용도로 세분화 충분하지만, 물론 모든 문서에 대한 계산을 할 필요없이 더 나은 성능을 제공한다.
이것은 당신이 이러한 코드 내의 모든 새 문서에 추가 할 몇 가지 셋업 기존 문서에 새 필드를 추가해야하고 확인하도록을 필요로한다. 간단한 변환 프로세스는 다음과 같을 수 있습니다 :
MongoDB를 4.2 및 위쪽
이것은 실제로는 집계 작업이 이제 "업데이트"문에서 허용되기에 단일 요청으로 수행 할 수 있습니다.
db.collection.updateMany( {}, [{ "$set": { "timeOfDay": { "$mod": [ { "$toLong": "$datetime_recorded" }, 1000 * 60 * 60 * 24 ] } }}] )
이전 MongoDB를
var batch = []; db.collection.find({ "timeOfDay": { "$exists": false } }).forEach(doc => { batch.push({ "updateOne": { "filter": { "_id": doc._id }, "update": { "$set": { "timeOfDay": doc.datetime_recorded.valueOf() % (60 * 60 * 24 * 1000) } } } }); // write once only per reasonable batch size if ( batch.length >= 1000 ) { db.collection.bulkWrite(batch); batch = []; } }) if ( batch.length > 0 ) { db.collection.bulkWrite(batch); batch = []; }
새 컬렉션에 쓰기로 감당할 수있는 경우에, 루핑 및 필요하지 않을 것입니다 재 작성 :
db.collection.aggregate([ { "$addFields": { "timeOfDay": { "$mod": [ { "$subtract": [ "$datetime_recorded", Date(0) ] }, 1000 * 60 * 60 * 24 ] } }}, { "$out": "newcollection" } ])
또는 MongoDB를 4.0 위쪽 :
db.collection.aggregate([ { "$addFields": { "timeOfDay": { "$mod": [ { "$toLong": "$datetime_recorded" }, 1000 * 60 * 60 * 24 ] } }}, { "$out": "newcollection" } ])
모두의 동일한 기본 변환을 사용하여 :
실제로 내부적으로 BSON 날짜로 저장된 값입니다 시대 이후 숫자 밀리 초에서 모듈은 하루에 현재의 밀리 초 단위로 추출 할 수있는 간단한 일입니다.
쿼리는 정말 간단하고, 질문의 예에 따라 :
db.collection.find({ "timeOfDay": { "$gte": 12 * 60 * 60 * 1000, "$lt": 16 * 60 * 60 * 1000 } })
물론 저장된 형식과 일치하는 밀리 초 단위로 시간에서 동시에 스케일 변환을 사용하여. 하지만 당신은 할 수 있습니다 직전처럼 확장 어떤이 실제로 필요합니다.
그렇지 않은 실제 문서 속성은 런타임에 계산에 의존으로 가장 중요한 것은, 당신은이에 인덱스를 배치 할 수 있습니다 :
db.collection.createIndex({ "timeOfDay": 1 })
그래서뿐만 아니라 계산이 무효화 런타임 오버 헤드가 있지만, MongoDB를위한 색인에 링크 된 페이지에 설명 된대로도 지수는 수집 검사를 피할 수 있습니다.
그것은 단순히보다는 당신이 원하는 어떤 것들을 해결하기 위해 컬렉션에있는 모든 문서를 처리 할 이상 크기의 순서 단순히 인덱스를 참조하고 만 문서를 가져 소요 실제 세계 규모로 최적의 성능을 위해 당신은 그런 일을 계산하고 싶지는 않을 .
집계 프레임 워크는 당신이 여기에 문서를 다시 도움을 줄 수 있습니다,하지만 정말 이러한 데이터를 반환하는 생산 시스템의 방법으로 사용되어서는 안된다. 별도로 시간을 저장합니다.
from https://stackoverflow.com/questions/17834596/mongodb-querying-between-a-time-range-of-hours by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 시간이 초과 CompositeServerSelector를 사용하여 서버를 선택 30000ms 후에 발생한 (0) | 2019.12.12 |
---|---|
[MONGODB] MongoDB를 집계 프레임 워크 :합니까 $ 단체 이용 지수? (0) | 2019.12.12 |
[MONGODB] $ 슬라이스 연산자를 사용하여 MongoDB의에서 배열의 마지막 요소를 얻을 수 있습니다 (0) | 2019.12.12 |
[MONGODB] ISODate 객체 밀리 초 변환 날짜 (0) | 2019.12.12 |
[MONGODB] 어떻게 필드 이름에 점 사용 하는가? (0) | 2019.12.12 |