복붙노트

[MONGODB] MongoDB를이 - 시간의 시간 범위 사이에 쿼리

MONGODB

MongoDB를이 - 시간의 시간 범위 사이에 쿼리

나는이 같은 저장된 위치 데이터와 설정 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. ==============================

    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. ==============================

    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를위한 색인에 링크 된 페이지에 설명 된대로도 지수는 수집 검사를 피할 수 있습니다.

    그것은 단순히보다는 당신이 원하는 어떤 것들을 해결하기 위해 컬렉션에있는 모든 문서를 처리 할 이상 크기의 순서 단순히 인덱스를 참조하고 만 문서를 가져 소요 실제 세계 규모로 최적의 성능을 위해 당신은 그런 일을 계산하고 싶지는 않을 .

    집계 프레임 워크는 당신이 여기에 문서를 다시 도움을 줄 수 있습니다,하지만 정말 이러한 데이터를 반환하는 생산 시스템의 방법으로 사용되어서는 안된다. 별도로 시간을 저장합니다.

  3. from https://stackoverflow.com/questions/17834596/mongodb-querying-between-a-time-range-of-hours by cc-by-sa and MIT license