如何使用spring在mongodb中进行智能更新?

时间:2015-11-09 16:15:32

标签: mongodb spring-data-jpa spring-data-mongodb

在mongo db中是否有智能且优化的数据更新方式?我现在以下面的方式做,但想用更少的数据库调用来做。

@Transactional
public void modifyParticipant(String id, String roomId, updates) {
    Conference conference = conferenceRepository.findParticipantsByRoomId(roomId);
    for(Participant participant : conference.getParticipants()){
        if(participant.getId().equals(id)){
            //modify the participant
            break;
        }
    }
    conference.updateTime();
    conferenceRepository.save(conference);
    }

我尝试了以下方式,但我从未成功,因为即使我试图只获得一个与id匹配的参与者,查询也会获得参与者数组。由于数组更新失败。

尝试

@Override
public void modifyParticipants(String id, String roomId, Map<String, String> map) {

    Query query = new Query();
    query.addCriteria(new Criteria().andOperator(Criteria.where("_id").is(roomId), Criteria.where("participants").elemMatch(Criteria.where("_id").is(id))));
    Conference conference = operations.findOne(query, Conference.class);
    String temp;
    Update update = new Update();
    if((temp = map.get("firstName")) != null){
        update.push("participants.$.firstName",temp);
    }
    if((temp = map.get("lastName")) != null){
        update.push("participants.$.lastName", temp);
    }
    if((temp = map.get("avatarUrl")) != null){
        update.push("participants.$.avatarUrl",temp);
    }
    if((temp = map.get("state")) != null){
        update.push("participants.$.state", temp);
    }
    if((temp = map.get("avState")) != null){
        update.push("participants.$.avState", temp);
    }
    operations.updateFirst(query, update, Conference.class);
}

数据结构

{ 
    "_id" : "f9091ed9-c828-4b52-b1c3-44e42f719694", 
    .....,
    "participants" : [
        {
            "_id" : "6b49b373-1e61-4c98-a703-c1c2bc4da0e2", 
            "deviceId" : "7F55271D-946C-44B0-BFAC-461447021762", 
            "avatarUrl" : "", 
            "firstName" : "ddd", 
            "lastName" : "qwr", 
            "state" : "REMOVED", 
            "about" : "", 
            "avState" : "OFFLINE", 
            "version" : NumberInt(0), 
            "timeCreated" : ISODate("2015-11-09T00:36:41.585+0000")
        }, 
        {
            "_id" : "48f32b8e-3c40-48c2-96fa-74e93c388cd1", 
            "deviceId" : "7F55271D-946C-44B0-BFAC-461447021762", 
            "avatarUrl" : "", 
            "firstName" : "wer", 
            "lastName" : "wrf", 
            "state" : "ONLINE", 
            "about" : "", 
            "avState" : "OFFLINE", 
            "version" : NumberInt(0), 
            "timeCreated" : ISODate("2015-11-09T00:37:24.574+0000")
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

理想情况下,您希望mongo shell等效于以下更新操作,该操作使用 $set 运算符和 $ positional 运算符标识要更新的数组中的元素,而不显式指定元素在数组中的位置。这意味着在update语句的查询端匹配数组元素的任何条件只匹配找到的第一个数组索引:

$('button').on('click', function(){
     $(this).addClass('animated flipInY');
}

Spring Data MongoDB示例等效如下:

db.conference.update(
    {
        "_id": "f9091ed9-c828-4b52-b1c3-44e42f719694",
        "participants._id": "6b49b373-1e61-4c98-a703-c1c2bc4da0e2"
    },
    {
        "$set": {
            "participants.$.firstName": "foo",
            "participants.$.lastName": "bar"
        }
    }
)