2012-06-14 2 views
0

어제 MongoDB에서 이상한 경험을했습니다. 내가 트위스트와 txmongo - mongodb (pymongo와 비슷한) 용 비동기 드라이버를 사용하고 있습니다.MongoDB 날짜 및 제거 된 객체

나는 데이터를 수신하여 mongodb에 저장하는 휴식 서비스를 제공합니다. 하나의 필드는 밀리 초 단위의 타임 스탬프, 13 자리입니다.

우선, 밀리 초 타임 스탬프를 파이썬의 파이썬 datetime으로 변환하는 것은 쉬운 일이 아닙니다. 이 같은 뭔가 결국 :

def date2ts(ts): 
    return int((time.mktime(ts.timetuple()) * 1000) + (ts.microsecond/1000)) 


def ts2date(ts): 
    return datetime.datetime.fromtimestamp(ts/1000) + datetime.timedelta(microseconds=(ts % 1000)) 

문제는 내 기능을 사용하여 MongoDB를 다시 날짜를 retreive와 타임 스탬프로 다시 변환 할 데이터를 저장할 때 내가 밀리 초 단위로 동일한 결과를 얻을 수 없다는 것입니다.

나는 왜 그런 일이 일어나고 있는지 이해하지 못했습니다. Datetime은 mongodb에 ISODate 객체로 저장됩니다. 나는 그것을 껍질에서 질문하려고했는데 실제로는 1 초 또는 몇 밀리 초에 차이가있다.

질문 1 : 왜 이런 일이 일어나는 지 알고 있습니까?

그러나 이것은 끝나지 않았습니다. 나는 datetime을 사용하지 않고 timestamp를 직접 저장하지 않기로 결정했다. 그 전에는 수집에서 모든 데이터를 제거했습니다. 같은 필드를 날짜와 같지 않고 저장하려고 시도했을 때 셸에서 ISODate로 표시된다는 사실에 상당히 놀랐습니다. 그리고 검색 할 때 수 밀리 초 안에 여전히 차이가있었습니다.

나는 색인 및 색인을 삭제하려고 시도했다. 도움이되지 않았을 때 전체 데이터베이스를 삭제하려고했습니다. 도움이되지 않았을 때 전체 데이터베이스를 삭제하고 mongod를 다시 시작하려고했습니다. 그리고이 후에 나는 그것을 Long으로 저장하기 시작했다고 생각합니다.

질문 2 : 왜 이런 일이 일어나는 지 알고 있습니까?

고맙습니다!

답변

0

파이썬의 타임 스탬프가 1 월 1 일 1970 년 (MongoDB를 차례로) 자바 스크립트의 타임 스탬프의 유닉스 시대 이후 에서 계산됩니다, 다른 한편으로는, 밀리 초의 측면에서입니다.

즉, 타임 스탬프 만 가지고 있다면 파이썬 값을 1000 배로하여 밀리 초를 얻고 그 값을 MongoDB에 저장할 수 있습니다. 마찬가지로 MongoDB의 값을 파이썬 타임 스탬프로 만들기 위해 1000으로 나눕니다. 파이썬은 단지 3 자리가 아닌 소수점 뒤에 2 자리의 유효 자릿수를 두는 것처럼 보입니다 (보통 밀리 초는 신경 쓰지 않으므로). 따라서 여러분은 여전히 ​​< 10 밀리 초의 차이점이 있다면이를 명심하십시오.

일반적으로 대신 튜플을 사용하는 것이 좋지만 각 언어별로 값 범위 규칙이 다릅니다 (JavaScript는 1 대신 0으로 시작하는 점에서 직관력이 없음) 문제가 발생할 수 있습니다. .

+0

timestamp 필드로 정확한 쿼리를 작성하려면 밀리 초 단위로 저장해야합니다.가장 쉬운 방법은 타임 스탬프를 오래 저장하는 것입니다. –

+0

"파이썬의 타임 스탬프는 초 단위로 계산됩니다"datetime에는 마이크로 초 필드가 있으며 실제로는 밀리 초 타임 스탬프를 저장할 수 있습니다. 나는 txmongo 운전사가 잘못된 길을가는 것 같아요. –

+0

이 주석을 찾았습니다. [pymongo 드라이버 소스] (https://github.com/mongodb/mongo-python-driver/blob/master/bson/son.py#L65) : datetime.datetime 인스턴스는 가장 가까운 위치로 반올림됩니다. 저장시 밀리 초 –

0

다른 시간대의 경우 일 수 있습니다. 아래에 언급 된 기능을 사용하여 수정하십시오.

function time_format(d, offset) { 
    // Set timezone 
    utc = d.getTime() + (d.getTimezoneOffset() * 60000); 
    nd = new Date(utc + (3600000*offset)); 
    return nd; 
} 

searchdate = time_format(searchdate, '+5.5'); 

'+5.5'여기는 현지 시간과 GMT 시간의 시간대 차이입니다.

+0

안녕하세요. 있을 수있다. 그러나 나는 그것이 정말로 사실이라고 생각하지 않는다. mongo와 app가 동일한 서버에 있고 초 단위의 차이가 분이 아니기 때문에. 퍼쿠션 문제 같아. –