2013-03-18 2 views
2

this document에 따라 사전 집계 된 성능 메트릭을 샤드 mongodb에 저장하려고합니다.pymongo 및 사용자 정의 _id 필드로 업다운

self.collection.update(query, data, upsert=True) 

쿼리 :

나는 정도 같은 upsert에 존재하지 않을 수있는 레코드의 분 하위 문서 업데이트하기 위해 노력하고있어

(self.collection는 pymongo 수집 인스턴스)

{ '_id': u'12345CHA-2RU020130304', 
    'metadata': { 'adaptor_id': 'CHA-2RU', 
        'array_serial': 12345, 
        'date': datetime.datetime(2013, 3, 4, 0, 0, tzinfo=<UTC>), 
        'processor_id': 0} 
} 

데이터 :

{ 'minute': { '16': { '45': 1.6693091}}} 

문제가 있음이 케이스 '분'에 하위 문서는 항상 마지막에 hour: { minute: metric} 항목 만 있고, 분 하위 문서는 다른 시간에 대한 새 항목을 만들지 않으며 항상 한 항목을 덮어 씁니다.

{ '$set': { 'minute': { '16': { '45': 1.6693091}}}} 

을하지만 같은 것을 끝 :

나는 또한 $ 세트 스타일 데이터 입력이 시도했습니다.

내가 뭘 잘못하고 있니?

답변

2

나열된 두 예제 모두에서 필드 ('minute')를 특정 값으로 설정하기 만하면 필드 자체가 존재하지 않으므로 작성해야하기 때문에 처음으로 업데이트 할 때 추가되는 유일한 이유입니다.

여기서 정확히 무엇을 촬영하는지 결정하기는 어렵지만, 스키마를 조금 바꾸어서 'minute'이 배열 인 것으로 생각합니다. 그런 다음 $push을 사용하여 이미 존재하는지 여부에 관계없이 값을 추가하거나 중복을 원하지 않는 경우 $addToSet을 사용할 수 있습니다.

나는, 그래서 셸에서이 유효 만들 조금 문서를 변경했다 내 _id (및 일부 다른 필드는) 당신에 약간 다릅니다,하지만 여전히 설명 할 수있을만큼 가까워 야한다 :

db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty() 
{ 
     "_id" : "u12345CHA-2RU020130304", 
     "metadata" : { 
       "adaptor_id" : "CHA-2RU", 
       "array_serial" : 12345, 
       "date" : ISODate("2013-03-18T23:28:50.660Z"), 
       "processor_id" : 0 
     } 
} 
내가 $addToSet을이되어 사용하고 있기 때문에

db.foo.update({'_id': 'u12345CHA-2RU020130304'}, { $addToSet : {'minute': { '16': {'45': 1.6693091}}}}) 
db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty() 
{ 
     "_id" : "u12345CHA-2RU020130304", 
     "metadata" : { 
       "adaptor_id" : "CHA-2RU", 
       "array_serial" : 12345, 
       "date" : ISODate("2013-03-18T23:28:50.660Z"), 
       "processor_id" : 0 
     }, 
     "minute" : [ 
       { 
         "16" : { 
           "45" : 1.6693091 
         } 
       } 
     ] 
} 
다음

이 추가을 설명하기 위해, (약간 다른 항목을 추가

지금의 대신에 하나의 문서의 문서의 배열을 가진 minute 필드를 추가 할 수 새로운 분야에 필요한 추가되는 :

db.foo.update({'_id': 'u12345CHA-2RU020130304'}, { $addToSet : {'minute': { '17': {'48': 1.6693391}}}}) 
db.foo.find({'_id': 'u12345CHA-2RU020130304'}).pretty() 
{ 
     "_id" : "u12345CHA-2RU020130304", 
     "metadata" : { 
       "adaptor_id" : "CHA-2RU", 
       "array_serial" : 12345, 
       "date" : ISODate("2013-03-18T23:28:50.660Z"), 
       "processor_id" : 0 
     }, 
     "minute" : [ 
       { 
         "16" : { 
           "45" : 1.6693091 
         } 
       }, 
       { 
         "17" : { 
           "48" : 1.6693391 
         } 
       } 
     ] 
} 
+0

배열에 항목으로'hours : minutes'을 저장하지 않으면 위에서 언급 한 링크에 명시된 탐색 혜택이 무효화됩니까? 또한 "_id"에 포함 된 'u'는 거기에 존재하지 않으므로 유니 코드를 나타내는 Python 인쇄물입니다. 고마워, 나는 이것에 대해 생각할 것이다. –

2

내가 이런 식으로 필드를 설정 결국 :

쿼리

{ '_id': u'12345CHA-2RU020130304', 
    'metadata': { 'adaptor_id': 'CHA-2RU', 
        'array_serial': 12345, 
        'date': datetime.datetime(2013, 3, 4, 0, 0, tzinfo=<UTC>), 
        'processor_id': 0} 
} 

나는이 같은 측정 기준을 설정하고 있습니다 :

data = {"$set": {}} 

for metric in csv: 
    date_utc = metric['date'].astimezone(pytz.utc) 
    data["$set"]["minute.%d.%d" % (date_utc.hour, 
           date_utc.minute)] = float(metric['metric']) 

다음과 같은 데이터를 생성합니다.

{"$set": {'minute.16.45': 1.6693091, 
      'minute.16.46': 1.566343, 
      'minute.16.47': 1.22322}} 

따라서 self.collection.update(query, data, upsert=True)을 실행하면 해당 필드가 업데이트됩니다.

관련 문제