Query DBRef with Spring Data MongoDB using QueryDSL - mongodb

I'm using Spring Data MongoDB and QueryDSL to perform some simple queries, but I'm having issues trying to use a predicate with a DBRef object's field.
It seems the DBRef are not resolved, so the query always returns empty results. There are some questions about this topic from 2014 mostly, and although there seem to have been some work done about it on both QueryDSL and Spring Data's side I still can't make it work and didn't find any working example.
I'm looking for a simple solution, as in the following simplified test case:
#Document
class Foo {
#Id Integer id;
#DBref Bar bar;
}
#Document
class Bar {
#Id Integer id;
String name;
}
interface FooRepository extends MongoRepository<Foo, Integer>, QueryDslPredicateExecutor<Foo> { ... }
and the query I'm trying to use :
fooRepository.findAll(QFoo.foo.bar.name.eq("test"))
I'm using QueryDSL 4.1.4, Spring Boot 1.5.3 with Spring Data MongoDB 1.10.3
Is this supported? Am I missing anything?

TL;DR;
It's not supported.
Explanation
You're expressing a predicate that follows the reference into a different document.
MongoDB is a document-oriented database that knows no joins. Each document may contain subdocuments or references (which are sort of artificial). Also, each document has to be either looked up individually or fetched as a collection of documents based on a query.
Because there are no joins built-in to MongoDB you can't query across DBRef references. You can express a query that scans the subdocument as the subdocument is embedded.
Spring Data MongoDB exposes functionality provided by MongoDB in a more user-friendly way and does not pretend to provide functionality that isn's supported by MongoDB.
Since MongoDB 3.4, the aggregation framework supports $graphLookup to let MongoDB lookup during the aggregation stage to look up individual documents. Lookups are expensive and that's something you'd rather want to avoid.

Related

How can we achieve MongoDB DBRefs in QUARKUS - MONGODB WITH PANACHE?

I was following the below guidelines to implement MongoDB ORM in my Quarkus server app.
QUARKUS - SIMPLIFIED MONGODB WITH PANACHE
https://quarkus.io/guides/mongodb-panache
How can I achieve document reference with this?
For example: If I have 2 entities like Employee, Organisation then how can I refer Organisation in my Employee entity?
Quarkus MongoDB with Panache didn't offers specific support for dbref.
You may be able to use a field of type com.mongodb.DBRef but we will not automatically load the document referenced by it so you need to do it by yourself.

Specify raw aggregate request with Spring Data Mongodb

I write a big aggregate query for mongodb, now I try to translate it in Spring Data Mongodb API, and it's very complicated, and spring data api did not help me a lot.
So like with #Query annotation, is it possible to just specify my raw aggregate query in text and map my field with Spring Data (or just Mongodb Java driver) ?
I won't c/p my aggregate request because, it's not the purpose of my question.
I found a solution by using MongoDB java driver, which is available through Spring Data :
DBCollection collection = mongoTemplate.getCollection("myCollection");
and I used BasicDBObject from this solution : MongoDB aggregation with Java driver

How to query MongoDB collection using mongoose discriminators

I am trying to read from a Mongo database using mongoose where the models make use of the discriminator inheritance functionality, but the documents in the DB are all inserted by another service (using the Java Mongo driver) which does not use mongoose nor its discriminators. All of my queries using subclass models (those which use the discriminator function) return empty arrays when I try to read from the DB. I think it's because mongoose is expecting those documents to contain a discriminator key, however the service which is inserting the documents has no knowledge of discriminator keys, and thus isn't setting them on the mongoDB documents.
How can I create my models and use the discriminator function such that they can still query for these documents inserted by another service?
For more context, I want to use discriminators because inheritance allows me to cleanly structure the fields of the models I'm creating and define model-specific static methods, and it lets me not write duplicate code. If there is a better way to accomplish these goals without using mongoose's built-in discriminator pattern, please share!
According to the documentation:
The way mongoose tells the difference between the different
discriminator models is by the 'discriminator key', which is __t by
default. Mongoose adds a String path called __t to your schemas that
it uses to track which discriminator this document is an instance of.
Also mongoose saves documents with discriminators to the single collections.
So, in order to have access to the documents you need to save __t parameter, and check if you save schemas with the same discriminators to a single collection

How can i obtain domain class of a collection in spring data mongodb

I transferred a table from postgresql to mongodb.I want to map this collection to a class. Is there a easy way to create the class of this collection ?
Well,
If you already created mongo DB. you could use java classes generator for json.
All documents in mongodb are represented in json.
Look at the answers for this question Generate Java class from JSON?

How to use DBCursor provided in mongodb java driver in spring-data-mongodb?

I want to read around 1 million documents from my mongodb database and I am using spring data mongodb. I do not want to read all of 1 million data at once for performance reasons. Is there any way in spring-data-mongodb to do this. In raw java driver we have DBCursor.
One way i know is using pagination through repositories. Is there any other way in latest versions of spring data mongodb?
Yes. You can use pagination with spring data mongodb. MongoRepository extends from PagingAndSortingRepository which means you can call findAll(Pagable) and provide page information.
Alternatively, you can use mongoOperations/mongoTemplate to get a DBCollection reference, and then call find() on the collection and that will return you the DBCursor you want.