让我说我有这个对象:
{
"_class" : "com.foo.Person",
"_id" : "2894",
"name" : "Pixel Spacebag",
"photos" : [
{
"_id" : 10,
"amount" : "100"
},
{
"_id" : 11,
"amount" : "200"
}
]
}
现在,我想在照片对象的“照片”数组中添加一个额外的字段。
我想在照片_id = 10中添加“发行商”字段:“Pixel Studios”。
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("2984"));
Update update = new Update();
update.set("distributor", "Pixel Studios");
mongoTemplate.updateFirst(query, update, Person.class);
我可以正确访问Person对象,但我无法正确更新specfic photo _id 10。
有谁知道如何正确更新?
答案 0 :(得分:1)
我挖了一会儿,实际上找到了解决方案。它以位置运算符的形式出现:
https://docs.mongodb.org/manual/reference/operator/projection/positional/
我还阅读了与位置运算符相关的这个线程,以及如何更新数组的元素:
com.mongodb.DBCollection collection = mongoTemplate.getDb().getCollection("person");
ObjectId _id = new ObjectId("2984");
ObjectId photos_id = new ObjectId(10);
BasicDBObject query = new BasicDBObject();
query.put("_id", _id);
query.put("photos._id", photos_id);
BasicDBObject data = new BasicDBObject();
data.put("photos.$.distributor", "Pixel Studios");
BasicDBObject command = new BasicDBObject();
command.put("$set", data);
collection.update(query, command);
答案 1 :(得分:0)
在客户端修改从数据库中获取的对象要容易得多
我在这里假设photos
内的文档是由_id
排序的,如果不是你必须在数组内搜索,那么还有一些步骤。
首先,这里是你如何在mongo shell(JavaScript)中执行此操作,但这在Java中应该没有太大的不同:
> v = db.ppl.find({_id: "2894"}).next();
{
"_id" : "2894",
"_class" : "com.foo.Person",
"name" : "Pixel Spacebag",
"photos" : [
{
"_id" : 10,
"amount" : "100"
},
{
"_id" : 11,
"amount" : "200"
}
]
}
> v.photos[0]
{ "_id" : 10, "amount" : "100" }
> v.photos[0].distributor = "pixel studios"
> v.photos[0]
{ "_id" : 10, "amount" : "100" }
> v.photos[0].distributor = "pixel studios"
> db.ppl.update({_id:"2894"}, {$set : {"photos": v.photos}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.ppl.findOne()
{
"_id" : "2894",
"_class" : "com.foo.Person",
"name" : "Pixel Spacebag",
"photos" : [
{
"_id" : 10,
"amount" : "100",
"distributor" : "pixel studios"
},
{
"_id" : 11,
"amount" : "200"
}
]
}
因此,在我使用.
进行分配的情况下,您必须使用适当的get或set方法,并为正确的类型进行可能的转换。
以下代码是我在上面发布的JS的Java等价物:
Document example = new Document("_class", "com.foo.Person")
.append("_id", "2894")
.append("name", "Pixel Spacebag");
List<Document> photos = new ArrayList<Document>();
photos.add(new Document("_id", 10).append("amount", "100"));
photos.add(new Document("_id", 11).append("amount", "200"));
example.append("photos", photos);
collection.insertOne(example);
FindIterable<Document> res = collection.find(new Document("_id", "2894"));
Document temp = res.iterator().next();
List<Document> photosDoc = (List<Document>) temp.get("photos");
Document docToUpdate = photosDoc.get(0);
docToUpdate.append("distributor", "pixel studios");
photosDoc.set(0, docToUpdate);
collection.updateOne(new Document("_id", temp.get("_id")),
new Document("$set", new Document("photos", photosDoc)));
/* Check that everything worked */
res = collection.find(new Document("_id", "2894"));
Document updatedDocument = res.iterator().next();
System.out.println(updatedDocument);
/* outputs:
Document{{_id=2894, _class=com.foo.Person, name=Pixel Spacebag, photos=[Document{{_id=10, amount=100, distributor=pixel studios}}, Document{{_id=11, amount=200}}]}}
*/