Morphia Mongodb Update in Embedded Array document fails - mongodb

I am new to Morphia and am trying to update a field in embedded document. This is the current structure
class A {
List<B> BList;
}
class B {
String field;
}
So My structure looks like the following in MongoDb :
{
"_id" : ObjectId("5bab8be0032945f6e9f91d98"),
"className" : "com.abc.A",
"BList" : [
{
"B" : {
"field" : "text"
}
}
}
Now I want to update B.field for all the matching queries.
I created the following UpdateOperations
UpdateOperations updateOps = datastore.createUpdateOperations(A.class);
my filter query was fine say filter returning me all elements in A.
updateOps.set("Blist.$[].B.field", "newtext");
when debugger reached this statement it shows org.mongodb.morphia.query.ValidationException: Could not resolve path 'BList.$[].B.field' against A`
I even added disableValidation But this doesnot run.
However if I ommit the positional operator it works fine but when on runnig datastore.update() it fails.
throwing this error.
Write failed with error code 28 and error message 'Cannot create field B.
Can Anyone suggest how to do this updation on second level in morphia ?

Related

How to retrieve values of nested objects in a Mongo DB document using java

I have a document like below:
"application" : "test",
"QA1" : {
"url" : "https://google.co.in",
"db" : {
"userName" : "user",
"password" : "pswd"
}
}
I want to retrieve the value "https://google.co.in" by calling the key "url".
While using the below shell command, I am able to retrieve the value as expected.
db.getCollection('Application_Data').findOne({"application":"test"}).QA1.url
But when I convert it to java code, it is throwing me null pointer exception:
cursor = collection.find(Filters.eq("application","test")).iterator();
while (cursor.hasNext()) {
value=cursor.next().get("QA1.url").toString();
break;
}
I also tried with projection like below to get the required values:
cursor = collection.find(Filters.and(Filters.eq("application","test"))).projection(Projections.fields(Projections.include("QA1.url"),Projections.excludeId())).iterator();
while (cursor.hasNext()) {
System.out.println(cursor.next().get("QA1").toString());
}
This is giving me the output as below:
Document{{url=https://google.co.in}}
It is still not giving me the exact value. Appreciate your help on this.
Mongodb Documents are nested. So say, in your example, when you do cursor.next().get("QA1"), you get the Document under "QA1" property.
So the way to achieve what you want is
cursor.next().get("QA1").get("url"). That, with proper error handling (think exceptions).
A better way to do what you want is to use a mapper like spring-data-mongodb that would map the JSON response of mongodb into a java object for you automatically.
You need to use the Document class's getEmbedded method to extract the nested field's value.
while (cursor.hasNext()) {
Document doc = cursor.next();
System.out.println(doc.toJson());
String urlValue = doc.getEmbedded(Arrays.asList("QA1","url"), String.class);
System.out.println(urlValue); // output below
}
The result is as expected - a string: https://google.co.in

How to correctly execute find query with comparing on long field in MongoDB?? Error code 2

My document have some long field:
{
"_id" : BinData(3,"qUlr7T//axtyJisrSnDRkw=="),
...
"next-run-date" : "2018-12-23T17:22:59.026Z",
"next-run-millis" : NumberLong("1540833792947"),
...
"_class" : "...domain.scheduling.ScheduleReportConfiguration"
}
I use Spring Data MongoDB (v2.0.5) and have a repository:
interface ScheduleReportConfigurationRepository extends MongoRepository<ScheduleReportConfiguration, UUID> {
List<ScheduleReportConfiguration> findByNextRunMillisLessThan( long milliseconds )
}
When I try to execute it a produced query is:
{ "next-run-millis" : { "$lt" : { "$numberLong" : "1544809451462" } } }
Question 1: Why it look like that?? When I try to execute it in DB, it no make sense. Why spring don't produce the query like: { "next-run-millis" : { "$lt" : NumberLong(1544809451462) } }??
In any case, both of these queries don't work. By first query I mean the repository method execution in my app integration test,by second - execution the query in mongo shell. The error:
org.springframework.data.mongodb.UncategorizedMongoDbException:
Query failed with error code 2 and error message 'error processing query:
ns=test.scheduleReportConfigurationTree: next-run-millis $lt 1544809451462
No query solutions' on server mongo:27017; nested exception is
com.mongodb.MongoQueryException: Query failed with error code 2 and error message
'error processing query: ns=test.scheduleReportConfigurationTree: next-run-millis $lt 1544809451462
Question 2: What do I wrong?? How me to make my query worked?? According to the docs, comparing operators should work fine with long.
Thank you for your answers and help.
I just needed to make my field indexed.

Mongo DB find() query error

I am new to MongoDB. I have a collection called person. I'm trying to get all the records without an _id field with this query:
db.person.find({}{_id:0})
but the error is
syntax error: unexpected {
but if i write
db.person.find()
it works perfectly.
Consider following documents inserted in person collection as
db.person.insert({"name":"abc"})
db.person.insert({"name":"xyz"}
If you want to find exact matching then use query as
db.person.find({"name":"abc"})
this return only matched name documents
If you want all names without _id then use projeciton id query as
db.person.find({},{"_id":0})
which return
{ "name" : "abc" }
{ "name" : "xyz" }
According to Mongodb manual you have little wrong syntax, you forgot to give comma after {}
Try this :
db.person.find({}, { _id: 0 } )

Improper date format in MongoDB Spring Data query criteria

I have an issue with a MongoDB query that I am having challenges with. In my class, I have a structure of [instance].events.destination.estimatedDateTime, and the value of estimatedDateTime is an ISO Date (eg. 2014-09-23 21:48:00.000Z). We are using org.springframework.data.mongodb.core.query.Criteria to append criteria to our query like this:
criteria = criteria.and("events.destination.estimatedDateTime").gte(today)
When this is generated, it looks like this when evaluated at runtime:
"events.destination.estimatedDateTime" : { "$gte" : { "$date" : "2014-10-28T05:00:00.000Z"} }
Unfortunately that is returning no records. I have taken that same condition and attempted to pull records in RoboMongo, but again there are no results. However, I have found that when I do the following in RoboMongo, I do indeed get results
"events.destination.estimatedDateTime" : { $gte : ISODate("2014-10-28T05:00:00.000Z") }
Is there a way using the Criteria class to generate ISODate(date) rather than "$date":date?

How many level can mongodb append sub-documents dynamicaly?

It seems that i can go further than one subdocument if i want to add it dynamicaly, here is the code:
db.users.update({"pup.cmn.id":id}, {"$addToSet":{"pup.cmn":{"abus":email}}})
this give error:
OperationFailure: can't append to array using string field name: cmn
then, if i add positional element i get this:
db.users.update({"pup.cmn.id":id}, {"$addToSet":{"pup.$.cmn":{"abus":email}}})
"cmn" :
[
{
"fto" : ObjectId("5190e8a53a5f3a0c102af045")
"id" : "14.05.2013 12:29:53"
},
{
"abus" : "u...#example.com"
}
]
so as you can see, it will add it in the same level, and i dont want that, because the application will get errors.
It seems that Mongodb for the time of writing (2.4.x) have not this feature, there is a ticket:
https://jira.mongodb.org/browse/SERVER-831