Aggregation with MongoDB 3.6 and Morphia 1.3.2 - java

I am trying to aggregate a MongoDB (3.6) using Morphia (1.3.2).
Currently it is a simple match and unwind to understand Morphia's API.
The problem that I am facing however is related to MongoDB 3.6:
Changed in version 3.4: MongoDB 3.6 removes the use of aggregate command without the cursor option unless the command includes the explain option. Unless you include the explain option, you must specify the cursor option.
This paragraph comes directly from the MongoDB documentation. MongoDB Aggregate.
This means that a cursor is mandatory for the aggregate to work. However, I can't find a way to do this using Morphia. Therefore my aggregate does not work.
AggregationPipeline data = aggregation.match(query).unwind("data");
Iterator<LoraHourData> out = data.aggregate(Data.class);
The error that is produced using above code is as follows :
Command failed with error 9: The cursor option is required, except for aggregate with the explain argument on server localhost:27017. The full response is { ok : 0.0, errmsg: The cursor option is required, except for aggregate with the explain argument", code : 9, codeName : FailedToParse }

Related

Couchbase Java SDK N1QL UPDATE issue

I'm experimenting with Java and Couchbase 6.0 Community edition using Java 2.7 SDK.
I'm trying to execute a simple update query from my java application the Couchbase Java 2.7 SDK:
String query ="UPDATE admin SET FIELDNAME='TEST'"
N1qlParams params = N1qlParams.build().adhoc(false);
N1qlQuery nquery = N1qlQuery.simple(query, params);
N1qlQueryResult nqr= this.rbucket.query(nquery);
And I am getting the following exception (the most meaningful part):
com.couchbase.client.core.CouchbaseException: N1qlQuery Error - {"msg":"syntax error - at UPDATE","code":3000}
The actual exception starts like this:
Exception in thread "main" com.couchbase.client.core.CouchbaseException: Error while preparing plan
Of course - this query works fine through the Couchbase web UI and I can update without problem.
Just for info: I tried escaping the single quotes, even tried setting the column to be equal to itself - same error.
Select queries are executed in a similar manner without any problem.
"admin' is not a good name for a bucket, as it is usually related to some reserved keywords, if you still want to use this name, you have to use backticks around it:
update `admin` set FIELDNAME = 'TEST'
It also might ask you to create a primary index if you don't have one yet.

Using JOOQ formatJSON to get column:value pairs

I'd like my formatJSON() result to be column:value pairs.
[{"ID":1,"AUTHOR_ID":1,"TITLE":"1984"},{"ID":2,"AUTHOR_ID":1,"TITLE":"Animal Farm"}]
This blog post (https://blog.jooq.org/2018/01/) suggests the result is possible by setting a formatting option flag somewhere, but I am unable to find how to specify that option. I am just getting the default (?) output:
{"fields":[{"schema":"sss","table":"ttt","name":"ccc1","type":"zzz"},{"schema":"sss","table":"ttt","name":"ccc2","type":"zzz"}],"records":[[1,"x"]]}
I am using jOOQ 3.7.0, but can upgrade if needed.
I am using jOOQ 3.7.0, but can upgrade if needed.
There's your answer. Upgrade to 3.9 or more to profit from #5372. You can then call Formattable.formatJSON(JSONFormat) like this:
String json = result.formatJSON(new JSONFormat()
.header(false)
.recordFormat(RecordFormat.OBJECT));

MongoDB Java Driver Equivalent of Snapshot for MongoCursor

After upgrading my MongoDB Java driver from version 2.14 to 3.2, I changed from using DBCursor to MongoCursor.
Previously, I was using snapshot() to prevent repetition when iterating through my large database of thousands of documents. However, I can't seem to find equivalent method for MongoCursor. This is causing troubling repetitions, e.g. 5571 loops for 4493 documents. That's like 24% more iterations! OMG!
So, my question is, is there a simple way or an equivalent method for MongoCursor that can prevent this from happening? If not, should I switch back to using DBCursor? It looks to still be supported in version 3.2.
Please kindly advise! Thank you!
After banging a few things through an checking the profiler logs I actually got a confirmation on this:
MongoCursor<Document> cursor = collection.find().modifiers(
new Document("$snapshot", true)
).iterator();
So you need to call the .modifiers() while still on a FindIterable with $snapshot as true. This is consistent over the wire with the .snaphot() cursor modifier.
Both record in the profiler like this:
"query" : {
"find" : "sample",
"filter" : {
},
"snapshot" : true
},
Showing the correct modifier placed.

MongoDB + Morphia - full text search using AND instead of OR

I've setup full text search and MongoDB and it's working quite well (Mongo 2.6.5).
However it does an OR instead of and AND.
1) Is it possible to make the query an AND query, while still getting all the benefits of full text search (stemming etc.)
2) And if so, is it possible to add this option via the Morphia wrapper library
EDIT
I see that the full text search includes a 'score' for each document returned. Is it possible to only return docs with a certain score or above. Is there some score that would represent a 'fuzzy' and query. That is usually all tokens are in the document but not absolutely always. If so this would solve the problem as well.
Naturally if possible to do this via Morphia that would be super helpful. But I can use the native java driver as well.
Any pointers in the correct direction, much appreciated.
EDIT
Code looks like this, I'm using Morphia 1.0.1:
Datastore ds = Dao.instance().getDatabase();
Query<Product> q = ds.createQuery(Product.class).search("grey vests");
List<Product> prods = q.asList();
Printing the query gives:
{ "$text" : { "$search" : "grey vests"}}
Note: I am able to do take an intersection of multiple result sets to create an AND query. However this is very slow since something like "grey" will return a massive result set and be slow at feeding the results back.
EDIT
I've tried to chain the search() calls and add a single 'token' to each call. But I am getting a run time error. Code becomes:
q.search("grey").search("vests");
The query I get is (which seems like it's doing the right thing) ...
{ "$and" : [ { "$text" : { "$search" : "grey"}} , { "$text" : { "$search" : "vests"}}]}
The error is:
com.mongodb.MongoQueryException: Query failed with error code 17287 and error message 'Can't canonicalize query: BadValue Too many text expressions' on server ...
at com.mongodb.connection.ProtocolHelper.getQueryFailureException(ProtocolHelper.java:93)

How to retrieve a subset of fields using the Java MongoDB driver?

new poster here, I found this previous post but it's on C#,
I tried doing this query straight into the java code of a JSP page, for some reason, it doesn't accept the info in the {} of the find() query and just gives out an error...
So peeps, how do I do this in Java:
// retrieve ssn field for documents where last_name == 'Smith':
db.users.find({last_name: 'Smith'}, {'ssn': 1});
Thanks!
PS: why the hell does C# have the nice little .Exclude() and .Include() commands and java doesn't? cries
The java driver follows the exact same API as the shell. Just pass a DBObject containing your field projection as the second argument to find or findOne
As far as I know the official C# driver doesn't expose Include() and Exclude() methods as they violate the standard API.

Categories