2013-06-14 2 views
1

내가 한 수집에서 조회하고 자바 API를 사용하여 다른에 삽입하기 위해 노력하고있어,하지만 난 이해가 안 예외 받고 있어요 :MongoDB를 : 예외 "부분 객체를 저장할 수 없습니다"

Exception in thread "main" java.lang.IllegalArgumentException: can't save partial objects 
    at com.mongodb.DBCollection._checkObject(DBCollection.java:1380) 
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:222) 
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:205) 
    at com.mongodb.DBCollection.insert(DBCollection.java:57) 
    at com.mongodb.DBCollection.insert(DBCollection.java:100) 

문서 또는 다른 것을 호출해야하는 "완료"방법이 있습니까? 내 코드는 다음과 같이 진행됩니다

import com.mongodb.BasicDBObject; 
import com.mongodb.DB; 
import com.mongodb.DBCollection; 
import com.mongodb.DBCursor; 
import com.mongodb.DBObject; 
import com.mongodb.Mongo; 
import org.joda.time.DateTime; 
import org.joda.time.DateTimeZone; 

Mongo mongo = new Mongo("mongodb://..."); 
DB db = mongo.getDB("foo"); 
DBCollection rawCollection = db.getCollection("foo1"); 
DBCollection aggCollection = db.getCollection("foo2"); 

DateTimeZone tz = DateTimeZone.forOffsetHours(-5); 

BasicDBObject toGrab = new BasicDBObject("Time1", 1).append("col2", 1).append("col3", 1); 
DBCursor c = rawCollection.find(null, toGrab).limit(10); 

for (DBObject doc : c) { 
    Date newDate = new DateTime(((BasicBSONObject) doc).getDate("Time1")) 
        .withZone(tz).monthOfYear().roundCeilingCopy() 
        .withZone(DateTimeZone.UTC).toDate(); 

    doc.put("Time2", newDate); 

    aggCollection.insert(doc); 
} 

답변

3

당신은 투사를 지정하여 collection.find (쿼리, 투사)

을 사용하여 특정 필드에 쿼리하는 검색 (find) 동작에 인수 컬렉션은 당신에게 부분 객체를 돌려줍니다.

게시 된 스택 추적에서 'insert'를 호출하면 기본 API가 _checkObject (doc)를 실행하고 커서가 반환 한 것과 동일한 인스턴스 인 '부분 개체'에 대해 예외를 throw합니다.

당신은 aggCollection에 복사본을 저장 한 후 효율적으로 반환 된 부분 객체를 복사 (새 BasicDBObject (문서))를 생성하고 의해이 문제를 얻을 수

..

BasicDBObject doc = ...; 
BasicDBObject copyOfDoc = new BasicDBObject(doc); 
copyOfDoc.put("Time2", newDate); 
aggCollection.insert(copyOfDoc); 

Find를 참조하고 collection sourcemap constructor .

+1

새 BasicDBObject (doc)와 같은 메소드가없는 것 같은데, 문서를 복제하는 다른 쉬운 방법이 있습니까? 아니면 현장으로 나가야합니까? –

+0

BasicDBObject 생성자는 Map을 사용하여 맵의 모든 속성을 가진 객체를 만듭니다. BasicDBObject는 또한 Map 인터페이스를 구현하므로 원본 객체를 Map 인스턴스로 사용하여 baseDBObject1과 동일한 모든 속성을 가진 새 BasicDBObject를 만들 수 있습니다 (polymorphism grand입니까?). 코드 예제를 사용하여 답변을 수정하겠습니다. – gbegley

+0

내가'BasicDBObject'는'Map'을 구현했지만 쿼리는'Map'을 구현하지 않는'DBObject'를 리턴합니다. 그래서 그냥 던지기 만하면 돼. 가장 예쁜 인터페이스는 아니지만 작동해야합니다. 감사합니다. –

관련 문제