使用Spring和Spring Data更新集合中的对象

时间:2017-11-23 16:13:58

标签: java spring mongodb spring-data

我试图将单个POJO保存到MongoDB集合中,然后更新同一个对象。它被称为"发现"对象,它有以下字段集:

private String displayName;
private String description;
private String contact;
private String defaultApiRoot;
private List<String> apiRoots;

我想&#34; displayName&#34;是唯一的,所以我创建一个像这样的索引:

mongoOperations.indexOps(Discovery.class)
    .ensureIndex(new Index().on("displayName", Sort.Direction.ASC));

创建索引,验证方式为:

> db.discovery.getIndexes()
[
  {
    "v" : 2,
    "key" : {
      "_id" : 1
    },
    "name" : "_id_",
    "ns" : "apiroot.discovery"
  },
  {
    "v" : 2,
    "key" : {
      "displayName" : 1
    },
    "name" : "displayName_1",
    "ns" : "apiroot.discovery"
  }
]

也许我误解了索引和Mongo或Spring Data,但是从我能够找到的每个SO问题和文档中,使用具有重复{{1}的发现对象执行.save()应该在该对象的字段上产生一个upsert。

我正在尝试按如下方式更新对象:

displayName

这导致两个对象:

Discovery discovery = discoveryRepository.findByDisplayName(displayName);
if (discovery.getApiRoots() == null || discovery.getApiRoots().isEmpty()) {
    discovery.setApiRoots(apiRoots);
} else {
    discovery.getApiRoots().addAll(apiRoots);
}
discoveryRepository.save(discovery);

当我尝试&#34;得到&#34;用的对象 > db.discovery.find() { "_id" : ObjectId("5a16ee397e7a1b3789c970a7"), "_class" : "....Discovery", "displayName" : "X", "description" : "Default Discovery Description", "contact" : "paul@arrakis.com", "defaultApiRoot" : "Default API Root Display Name" } { "_id" : ObjectId("5a16ee3f7e7a1b3789c970a8"), "_class" : "....Discovery", "displayName" : "X", "description" : "Default Discovery Description", "contact" : "paul@arrakis.com", "defaultApiRoot" : "Default API Root Display Name", "apiRoots" : [ "https://localhost:8001/Default+API+Root+Display+Name" ] } ,我明白了:

discoveryRepository.findByDisplayName(displayName)

我确信我只是完全忽略了Mongo如何在这里工作的标志,但如果有人能帮助阐明这一点我真的很感激。如果我可以进行单个DB调用来更新对象,则可以获得奖励积分。我知道对象的索引键,所以我不需要进行{ "display_name": "FLARE", "description": "Default Discovery Description", "contact": "paul@arrakis.com", "default": "Default API Root Display Name" } 调用,但在任何一种情况下我都无法使用它。

TL; DR:使用Spring和MongoDB,如何根据_id以外的索引键更新存储在集合中的对象的字段子集?

2 个答案:

答案 0 :(得分:1)

使用此声明

mongoOperations.indexOps(Discovery.class)
    .ensureIndex(new Index().on("displayName", Sort.Direction.ASC));  

您只是创建一个索引,这会使您的搜索更快,但并不是说您希望它是唯一的

这样做

mongoOperations.indexOps(Discovery.class)
        .ensureIndex(new Index().on("displayName", Sort.Direction.ASC).unique());  

答案 1 :(得分:1)

@pvpkiran所说的对于这个问题是正确的。对于主要问题,我使用以下代码根据标题更新特定的ApiRoot:

    Query query = new Query(new Criteria("title").is(apiRoot.getTitle()));
    Update update = new Update();
    update.set("description", apiRoot.getDescription());
    update.set("versions", apiRoot.getVersions());
    update.set("maxContentLength", apiRoot.getMaxContentLength());
    mongoOperations.upsert(query, update, apiRootCollection);