2012-08-17 4 views
6

Spring DataとMongoDBの最初の実験は素晴らしかったです。今、私は次の構造(簡体字)持っている:SpringデータMongoDB:サブ文書へのアクセスと更新

public class Letter { 
    @Id 
    private String id; 
    private List<Section> sections; 
} 

public class Section { 
    private String id; 
    private String content; 
} 

ロードを全体レターオブジェクト/文書を保存する魔法のように動作します。 (私はSection.idフィールドに一意のIDを生成するためのObjectIdを使用しています。)のドキュメントとして

Letter letter1 = mongoTemplate.findById(id, Letter.class) 
mongoTemplate.insert(letter2); 
mongoTemplate.save(letter3); 

は(200K)大、時には唯一のサブ部分がアプリケーションによって必要とされている:照会する可能性がありますサブ文書(セクション)、変更して保存?私は、変更、文書全体をロードする、つまり、最後の三つの方法がやや「奇妙」であることがわかり

addLetterSection(letterId, s); // add after last section 
insertLetterSection(letterId, sectionId, s); // insert before given section 
deleteLetterSection(letterId, sectionId); // delete given section 

:私は

Section s = findLetterSection(letterId, sectionId); 
s.setText("blubb"); 
replaceLetterSection(letterId, sectionId, s); 

など、もちろん法のような方法を実装したいと思います それを収集して保存することは、オブジェクト指向の観点からはより良いアプローチかもしれません。最初のユースケース(サブドキュメント/サブオブジェクトを「ナビゲート」してこのオブジェクトの範囲内で作業する)は当然のようです。

MongoDBはサブドキュメントを更新できますが、SpringDataをオブジェクトマッピングに使用できると思いますか?任意のポインターをありがとう。

答えて

12

私は、1つのサブオブジェクトだけをスライスして読み込むために次の方法を考え出しました。それは大丈夫と思われますか?私は同時修正の問題を認識しています。

Query query1 = Query.query(Criteria.where("_id").is(instance)); 
query1.fields().include("sections._id"); 
LetterInstance letter1 = mongoTemplate.findOne(query1, LetterInstance.class); 
LetterSection emptySection = letter1.findSectionById(sectionId); 
int index = letter1.getSections().indexOf(emptySection); 

Query query2 = Query.query(Criteria.where("_id").is(instance)); 
query2.fields().include("sections").slice("sections", index, 1); 
LetterInstance letter2 = mongoTemplate.findOne(query2, LetterInstance.class); 
LetterSection section = letter2.getSections().get(0); 

これは、すべてのセクションをロードする代替的な解決策であるが、他の(大)フィールドを省略します。

Query query = Query.query(Criteria.where("_id").is(instance)); 
query.fields().include("sections"); 
LetterInstance letter = mongoTemplate.findOne(query, LetterInstance.class); 
LetterSection section = letter.findSectionById(sectionId); 

これは私が唯一のシングルコレクション要素を格納するために使用するコードです:

MongoConverter converter = mongoTemplate.getConverter(); 
DBObject newSectionRec = (DBObject)converter.convertToMongoType(newSection); 

Query query = Query.query(Criteria.where("_id").is(instance).and("sections._id").is(new ObjectId(newSection.getSectionId()))); 
Update update = new Update().set("sections.$", newSectionRec); 
mongoTemplate.updateFirst(query, update, LetterInstance.class); 

春データのMongoDBから「部分的な結果」で使用することができる方法を見ていいです。

コメントありがとうございます。

+0

findSectionById()メソッドを共有できますか? –

+0

私はそれを共有して喜んで、それは簡単ですが、それは手紙のセクションをループし、IDフィールドを比較します。現時点では正確なコードはありません。 –

関連する問題