Reputation: 75
I am attempting to save a single POJO into a MongoDB collection, and then update that same object. It is called a "Discovery" object, and it has the following set of fields:
private String displayName;
private String description;
private String contact;
private String defaultApiRoot;
private List<String> apiRoots;
I want "displayName" to be unique, so I am creating an index like so:
mongoOperations.indexOps(Discovery.class)
.ensureIndex(new Index().on("displayName", Sort.Direction.ASC));
The index is created, as validated by:
> db.discovery.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "apiroot.discovery"
},
{
"v" : 2,
"key" : {
"displayName" : 1
},
"name" : "displayName_1",
"ns" : "apiroot.discovery"
}
]
Perhaps I am misunderstanding indexes and Mongo, or Spring Data, but from every SO question and piece of documentation I have been able to find, performing a .save()
with a Discovery Object that has a duplicate displayName
, should result in an upsert on the fields for that object.
I am trying to update the object as follows:
Discovery discovery = discoveryRepository.findByDisplayName(displayName);
if (discovery.getApiRoots() == null || discovery.getApiRoots().isEmpty()) {
discovery.setApiRoots(apiRoots);
} else {
discovery.getApiRoots().addAll(apiRoots);
}
discoveryRepository.save(discovery);
This results in two objects:
> db.discovery.find()
{
"_id" : ObjectId("5a16ee397e7a1b3789c970a7"),
"_class" : "....Discovery",
"displayName" : "X",
"description" : "Default Discovery Description",
"contact" : "[email protected]",
"defaultApiRoot" : "Default API Root Display Name"
}
{
"_id" : ObjectId("5a16ee3f7e7a1b3789c970a8"),
"_class" : "....Discovery",
"displayName" : "X",
"description" : "Default Discovery Description",
"contact" : "[email protected]",
"defaultApiRoot" : "Default API Root Display Name",
"apiRoots" : [
"https://localhost:8001/Default+API+Root+Display+Name"
]
}
And when I try to "get" the object with
discoveryRepository.findByDisplayName(displayName)
, I get:
{
"display_name": "FLARE",
"description": "Default Discovery Description",
"contact": "[email protected]",
"default": "Default API Root Display Name"
}
I am sure I am just completely missing the mark on how Mongo works here, but I would really appreciate if someone could help elucidate this. Bonus points if I can make a single DB call to update the object. I know the object's indexed key, so I don't really need to make the .find()
call, but I can't get it to work in either case.
TL;DR: Using Spring and MongoDB, how do I update a subset of fields for an object stored in a collection, based on an indexed key other than _id?
Upvotes: 0
Views: 549
Reputation: 75
What @pvpkiran said is correct for that question. For the main question, I used the following code to update a particular ApiRoot based on title:
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);
Upvotes: 1
Reputation: 27078
With this statement
mongoOperations.indexOps(Discovery.class)
.ensureIndex(new Index().on("displayName", Sort.Direction.ASC));
You are just creating a index, which will make your searches faster, but doesn't say you want it to be unique
Do this
mongoOperations.indexOps(Discovery.class)
.ensureIndex(new Index().on("displayName", Sort.Direction.ASC).unique());
Upvotes: 1