Check if value exists in mongodb - mongodb-java

I'm trying to write a method that will check if a user_id is in the DB and then operate on the user_id.The portion of code that I'm stuck on is this:
DBObject query = new BasicDBObject(user_id,new BasicDBObject("$regex", true));
DBCursor result = dBcollection.find(query);
if (result.equals("true")) {
System.out.println("found");
//do stuff
}
else{
//do other stuff
}
My database is set up this way:
{ "_id" : { "$oid" : "53b4443ad121894f16ea3699"} , "user_id" : "1683777896" , "countries" : { "JA" : 1}}
{ "_id" : { "$oid" : "53b4443ad121894f16ea369a"} , "user_id" : "453121657" , "countries" : { "TU" : 1}}
I want to be able to query on the user_id and then operate on the record associated with that user_id but I can't figure out the correct syntax in java for the "if" statement.

Use this to query for the document with that user id:
DBObject query = new BasicDBObject("user_id", user_id);
Use this for the if statement to determine if the find actually found that user id:
if (result.hasNext())
If that doesn't go into the if statement, show us the code that gets the database and dBcollection, and make sure you are connecting to the right database and collection name.

Related

Naming a Query Methods for MongoRepository with multiple conditions in SpringBoot

According to the documentation, I'm trying to get a working name for a method of a Spring MongoRepository that have to meet two different conditions. In plain words, the query sounds like: "look up for a determinate object by his id and it is one of mine or I want to share it"
The object:
{
"_id" : ObjectId("5c497..."),
"owner" : "myUserId",
"shared" : false,
}
The query:
db.getCollection('collection').find({$or : [
{ $and : [ { '_id' : ObjectId("5c497...") }, { 'owner' : 'myUserId' } ] },
{ $and : [ { '_id' : ObjectId("5c497...") }, { 'shared' : true } ] }
]})
I solved the problem with #Query
#Query("{\$or: [{\$and: [{'_id' : ?0}, {'owner' : ?1}]}, {\$and: [{'_id' : ?0}, {'shared' : true}]} ]}")
fun findIfAvailable(id: ObjectId, owner: String, shared: Boolean = true): Mono<MyObj>
But now, I wondered if it's possible to writing a method name for simplify the code ( and learn how use it ).
I tried without success findByIdAndOwnerOrShared, findByIdAndOwnerOrIdAndShared and so on
Thank you

OrOperator in MongoTemplate not returning values?

I am working on Spring MVC with MongoDB.
I have added criteria for some fields with orOperator, Each Fields has value in database, but List returning is Empty.
criteriaQuery.addCriteria(Criteria.where("First_Name").is(docName.trim())
.orOperator(Criteria.where("Middle_Name").is(docName.trim())
.orOperator(Criteria.where("Last_Name").is(docName.trim()))));
Query printing in console is
Query: { "First_Name" : "ESTHER" , "$or" : [ { "Middle_Name" : "ESTHER" , "$or" : [ { "Last_Name" : "ESTHER"}]}]}, Fields: null, Sort: null
I tried the Like query, but that also results the same
criteriaQuery.addCriteria(Criteria.where("First_Name").regex(docName)
.orOperator(Criteria.where("Middle_Name").regex(docName))
.orOperator(Criteria.where("Last_Name").regex(docName)));
Mongo Query
db.doctor_details.find({ "$or" : {"First_Name" : { "$regex" : "ESTHER"} }, "$or" : [ { "Middle_Name" : { "$regex" : "ESTHER"} , "$or" : [ { "Last_Name" : { "$regex" : "ESTHER"}}]}]})
Help me to get the result, I dont know where my code goes wrong. Help is appreciated!
Thanks
As far as I remember in order to use orOperator you should do:
Query query = new Query(new Criteria().orOperator(criteriaV1,criteriaV2));
it is based on this answer

Spring mongodb Find document if a single field matches in a list within a document

I have some data stored as
{
"_id" : ObjectId("abc"),
"_class" : "com.xxx.Team",
"name" : "Team 1",
"members" : [
{"userId" : 1, "email" : "a#x.com" },
{"userId" : 2, "email" : "b#x.com" },
]
}
{
"_id" : ObjectId("xyz"),
"_class" : "com.xxx.Team",
"name" : "Team 2",
"members" : [
{"userId" : 2, "email" : "b#x.com" },
{"userId" : 3, "email" : "c#x.com" }
]
}
I have 2 POJO classes Team (mapped to entire document),TeamMember (mapped to members inside a document).
Now I want to find to which team a specific user belongs to. For example if I search for a#x.com it should return me the document for Team 1. Similarly searching for b#x.com should return both of them as its in both the documents.
As I am very new to spring, not able to find out how to solve this.
Note: I am using MongoTemplate
somthing like this will do
final QueryBuilder queryBuilder = QueryBuilder.start();
//queryBuilder.and("members.email").is("a#x.com") This will work as well. try it out.
queryBuilder.and("members.email").in(Arrays.asList("a#x.com"))
final BasicDBObject projection = new BasicDBObject();
projection.put("fieldRequired", 1);
try (final DBCursor cursor = mongoTemplate.getCollection(collectionName).find(queryBuilder.get(), projection)
.batchSize(this.readBatchSize)) {
while (cursor.hasNext()) {
DBObject next = cursor.next();
........
// read the fields using next.get("field")
.........
}
}
batchsize and projection is not mandatory. Use projection if you don't want to fetch the whole document. You can specify which field in the document you want to fetch in the result.
You can use below code with the MongoTemplate
Query findQuery = new Query();
Criteria findCriteria = Criteria.where("members.email").is("b#x.com");
findQuery.addCriteria(findCriteria);
List<Team> teams = mongoTemplate.find(findQuery, Team.class);

Elastic search Update by Query to Update Complex Document

I have a use case of elastic search to update a doc.
My doc is something like this-
{
"first_name" : "firstName",
"last_name" : "lastName",
"version" : 1234,
"user_roles" : {
"version" : 12345,
"id" : 1234,
"name" : "role1"},
},
"groups" : {
"version" : 123,
"list": [
{"id":123, "name" : "ashd"},
{"id":1234, "name" : "awshd"},
]
}
}
Now depepeding on some feed I will either will be updating the parent doc or will be updating the nested doc.
I am able to find how to update the basic attributes like firstName and lastName but unable to get how to update complex/nested ones
I did something like from REST client-
"script": {
"inline": "ctx._source.user_roles = { "id" : 5678, "name" :"hcsdl"}
}
but its giving me exception-
Actual use case-
I will actually be getting a Map in java.
This key can be simple key like "first_name" or can be complex key like "user_role" and "groups"
I want to update the document using update by query on version.
The code I wrote is something like-
for (String key : document.keySet()) {
String value = defaultObjectMapper.writeValueAsString(document.get(key));
scriptBuilder.append("ctx._source.");
scriptBuilder.append(key);
scriptBuilder.append('=');
scriptBuilder.append(value);
scriptBuilder.append(";");
}
where document is the Map
Now I might get the simple fields to update or complex object.
I tried giving keys like user_roles.id and user_roles.name and also tried giving complete user_roles but nothing is working.
Can someone helpout
Try this with groovy maps instead of verbatim JSON inside your script:
"script": {
"inline": "ctx._source.user_roles = [ 'id' : 5678, 'name' : 'hcsdl']}
}

How to perform Sum on a Map Key in the Mongo DB document within Spring

My MongoDB document looks something like as following:
{
"_class" : "com.foo.foo.FooClass",
"_id" : ObjectId("5441948f3004e65fbda72d9c"),
"actionType" : "LOGIN",
"actor" : "bolt",
"extraDataMap" : {
"workHours" : NumberLong(11869)
},
}
Where extraDataMap is a HashMap stored from the java code. I have to get all the documents where "actionType" is "Login", group on "actor" and sum all the "workHours" for those individual actors
If I do below query on MongoDB directly it works:
db.activityLog.aggregate([
{$match : { actionType : "LOGIN" }},
{$group : { "_id" : "$actor", "hours" : { "$sum" : "$extraDataMap.workHours" } } },
{$sort : {_id : 1}}
]);
But If I run the query from Java Code
TypedAggregation<ActivityLog> agg = Aggregation.newAggregation(ActivityLog.class,
buildCriteria(),
group("actor").sum("extraDataMap.workHours").as("hours"),
sort(Sort.Direction.ASC, MongoActivityLogRepository.DOCUMENT_ID_FIELD_NAME)
);
AggregationResults<ActivityLog> result = mongoOperations.aggregate(agg, ActivityLog.class);
List<ActivityLog> results = result.getMappedResults();
It gives below error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property work found for type java.lang.String
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:290)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:274)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
at org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext.getReference(TypeBasedAggregationOperationContext.java:91)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:359)
at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDBObject(GroupOperation.java:355)
at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDBObject(GroupOperation.java:300)
at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:228)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1287)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1264)
at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1253)
Really appreciate all the prompt responses :)
I had the same problem than you and I found this solution
Instead of using TypedAggregation, use a plain Aggregation. This way, spring data won't perform a type checking.
It would be as follows:
Aggregation agg = Aggregation.newAggregation(
buildCriteria(),
group("actor").sum("extraDataMap.workHours").as("hours"),
sort(Sort.Direction.ASC, MongoActivityLogRepository.DOCUMENT_ID_FIELD_NAME)
);
List<ActivityLog> results = mongoOperations.aggregate(agg, mongoOperations.getCollectionName(ActivityLog.class), ActivityLog.class).getMappedResults();
See that I used a different mongoOperations.aggregate signature, because since we are not using a TypedAggregation, we have to indicate over which collection we are performing the aggregation.
I hope this helps you.

Resources