Count in Spring Data MongoDB repository - java

I wonder if there's any mechanism to use count in Spring Data MongoDB repository with #Query annotation?
I would love to receive the number of documents that I have without having to get all of them.
Basically, the equivalent of this in Java:
db.test.find({"type":"foo"}).count

Another way to do this using MongoRepository query templates:
public interface MyRepository extends MongoRepository<MyClass, String> {
Long countByLastname(String lastname);
}
See http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.query-methods.details

For me this solutions works like a charm( using spring-data-mongodb 1.3.1.RELEASE ),
I just had the same problem atm and solved it like this(just a short snippet from my code at work):
#Query(value = "{'productDetails.productType': {$regex: ?0, $options: 'i'}, 'sourceDescriptor': ?1}", count = true)
public Long countFetchedDocumentsForCategory(String cat, String sourceDescriptor);

I had same problem recently and unfortunately did not find any solution at least not with current stable version. It seems that it is possible in Spring Data JPA 1.4M1 so maybe it will be also included in next version of Spring Data MongoDB.

Related

filter Data in Spring Boot Data REST

I use Spring Boot Data REST, yes, I write something like below:
#RepositoryRestResource
public interface ExerciseRepository extends JpaRepository<Exercise, Integer> {}
then I open 127.0.0.1/exercises. It will show all exercises.
But I want only show some appointed exercises(eg. exercise id < 100, or other complicated logic) on the 127.0.0.1/exercises.
I know I can use #RestController, but how can I do this with Spring Boot Data REST?
#RepositoryRestResource(path="exercises",collectionResourceRel = "exercises")
can you edit this according to your own code ? I think this will work for you
You can declare an interface method, for example:
#RepositoryRestResource
public interface ExerciseRepository extends JpaRepository<Exercise, Integer> {
List<Exercise> findByIdLessThan(#Param("id") Integer id);
}
In this case, the query is derived from the method name directly, but you can also write a query manually using #Query, for more details check the documentation.
To invoke the method use the following API request:
GET http://localhost:8080/exercises/search/findByIdLessThan?id=100
For reference, Spring Data REST - Useful notes.
EDIT:
If you use Hibernate as your persistence provider, you can use #Where for static filtering, and #Filter for dynamic filtering where filters are defined and configured at runtime, according to Hibernate User Guide.
For example, you can annotate the entity with #Where and define a condition that will be applied to all queries related to that entity:
#Where(clause = "id<100")
#Entity
public class Exercise{
//...
}

Spring Repository without #Query

I am working on a desktop application built using spring framework and one of the part of the application is not working. I found that the repository class does not have any queries with #Query annotation. I haven't encountered it before.
When I try to open the form that uses this, I get an error that the application is not able to connect to the database. The application has 3 databases specified in the application.properties. I have the following questions:
1) How does the following code work without a query specified with #Query annotation. Or where is the query written.
#Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
List<Account> findAccountsByActiveIsTrueAndAccountTypeEquals(String accountType);
List<Account> findAccountsByAccountTypeLike(String type);
}
2) How do we specify which of the database to search for. For example: I have 3 mysql databases currently connected to my application. I wish to access data from DB1 through my Spring boot application through the usual flow of
UI model-> BE Controller/ Service layer -> Repository(Interface) which (usually) has the query written with #Query. How we specify which database this query goes for ?
For your first question I can answer that the JpaRepository has an internal system that analyses the method name you have written and then generates the query that has to be executed to the database.
The #Query annotation is used when the method name and the generated query is not returning the result you wanted to so you specifically tell the compiler which query should be executed.
As mentioned here: https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/jpa.repositories.html
2.3.1 Query lookup strategies.
The JPA module supports defining a query manually as String or have it being derived from the method name.
Declared queries
Although getting a query derived from the method name is quite convenient, one might face the situation in which either the method name parser does not support the keyword one wants to use or the method name would get unnecessarily ugly. So you can either use JPA named queries through a naming convention (see Section 2.3.3, “Using JPA NamedQueries” for more information) or rather annotate your query method with #Query (see Section 2.3.4, “Using #Query” for details).
So basically using a naming convention will do the magic.
Also an interesting question and perfect answer can be found here:
How are Spring Data repositories actually implemented?
For your second question you can refer to this example:
https://www.baeldung.com/spring-data-jpa-multiple-databases
It might be a bit complicated in the beginning but eventually it will work.
He use JPA, JpaRepository has CRUD methodes
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference
In your application.properties, you can put your mysql DB info
Why this works without #Query?
Because you are using JpaRepository which provides an easy way to get data based on your entity and it's fields.
Here your Account will have active, accountType etc fields. You can use JPA's query creation keywords such as AND, OR, Equals, Like and many more.
Derived queries with the predicates IsStartingWith, StartingWith, StartsWith, IsEndingWith", EndingWith, EndsWith, IsNotContaining, NotContaining, NotContains, IsContaining, Containing, Contains the respective arguments for these queries will get sanitized. This means if the arguments actually contain characters recognized by LIKE as wildcards these will get escaped so they match only as literals. The escape character used can be configured by setting the escapeCharacter of the #EnableJpaRepositories annotation.
How do we specify which of the database to search?
You can create configuration classes based on your databases and define data sources based on that using #PropertySource.
For more details see example here
#Configuration
#PropertySource({ "classpath:persistence-multiple-db.properties" })
#EnableJpaRepositories(
basePackages = "com.baeldung.multipledb.dao.product",
entityManagerFactoryRef = "productEntityManager",
transactionManagerRef = "productTransactionManager"
)

how to add group field in #Query annotation in Solr

I have added a method to get quarters my repository class based on the value of book and year
public interface Repository extends SolrCrudRepository<Doc, Long> {
#Query(fields = { Constants.QUARTER_FIELD })
public List<CodingClinicDoc> findQuarterByBookAndYear(String book, int year);
}
but i am getting duplicate values e.g. 'First quarter' around 10 times
Please tell me if there is a way to apply group field like group=true&group.field=quarter to #Query annotation to get unique result.
Or some other way to get the distinct quarters.
As of version 1.5.2 of Spring Data Solr, you cannot use result grouping with SolrRepository. You'll have to use SolrTemplate.
See this section (http://docs.spring.io/spring-data/solr/docs/1.5.2.RELEASE/reference/html/#solr.misc.group) on Spring data solr reference.

Regular expression Spring data mongodb repositories

Good morning,
I´m trying to combine regular expression with Spring data mongodb repository using Query annotation.
What I want is search one substring inside one string attribute of my mongo document.
I have been looking in google and here, but I did not find anything elegant, and I was wondering if Spring data has something official about this using the repositories.
Regards.
It seems like an old question, so maybe you've already had a solution but here how I handled the same issue :
#Query(value = "{'title': {$regex : ?0, $options: 'i'}}")
Foo findByTitleRegex(String regexString);
using the /?0/ notation won't work since Spring Data places a String value with quotes

How do I query for dates in Spring Data MongoDB repository?

My domain object -
Person{
String name;
Date born;
}
and I have a PersonRepository
PersonRepository{
#Query(value="{'born': {$gt: new Date(?0)} }")
findPerson(Date bornAfter);
}
I'm trying to fetch all Persons born after a certain date. That doesn't work though. What am I missing? The date-format for 'born' in mongodb console looks like
ISODate("2011-11-16T09:46:33.750Z")
I tried to look for a unit/integration test for this in data-jpa source. Couldn't find any. Can someone point me to it?
So first you have to make sure you don't mix up Spring Data JPA with Spring Data MongoDB here. I don't think any part of the question is actually targetting some JPA stuff. Here's how your Repository might look like:
public interface PersonRepository extends Repository<Person, Long> {
// Query generated from the method name
List<Person> findByBornGreaterThan(Date born);
#Query("{'born' : { '$gt' : ?0 }}")
List<Person> findPersons(Date born);
}
The latter does not work for 1.0.1.RELEASE and I have created a ticket for that and already fixed it for the upcoming versions 1.0.2.RELEASE and 1.1.0.M1. So you might wanna grab a snapshot build to try it. I have also created a ticket to add Before and After to the supported keywords for more intuitive use than LessThan and GreaterThan currently allow.
Either use the #Query annotation or use the key words in the method name. I'd advise to just stick with the key words in the method name. Which means this annotation can be removed. Means,
List<Person> findByBornGreaterThan(Date born);
will only work. You can refer https://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/repositories.html for more clarification.

Categories