how to add group field in #Query annotation in Solr - java

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.

Related

How to count number of rows based on enum value?

I have a database table where one of the columns contain an enum
Entity file:
#Entity
#Table(name = "error_log_entry")
public class ErrorLogEntryEntity extends AbstractPersistable<UUID> {
#Id
private UUID id;
#Column(name = "priority")
#Enumerated(EnumType.STRING)
private ErrorLogEntryPriorityType priority;
}
Enum file
public enum ErrorLogEntryPriorityType {
INFO,
WARN,
DANGER
}
Now I am trying to write a query that counts the number of rows where the enum is equal to "DANGER"
public interface ErrorLogEntryRepository extends JpaRepository<ErrorLogEntryEntity, UUID> {
List<ErrorLogEntryEntity> findByChangedUserId(UUID userId);
#Query(nativeQuery = true, value = "select count(*) from error_log_entry where priority = 'DANGER'")
ErrorLogEntryPriorityType getErrorCount();
}
However, this causes the following error
java.lang.ClassCastException: class java.math.BigInteger cannot be cast to class project.core.types.ErrorLogEntryPriorityType
I am a bit new to spring, but from the documentation, this problem seems to occur because I am casting on an incompatible type. I am not 100% sure.
Any suggestions on how to make this query work?
As mentioned in the comments, the error is because the return type of the query method you've defined is incorrect. You're not looking to get back an instance of ErrorLogEntryPriorityType, you need to get back a numerical value - the count of how may records match the query.
Having said that, there's an even easier, cleaner solution - use Spring Data's "derived query method" and you don't even need to write the #Query yourself. For example, this should work as you intend:
long countByPriority(ErrorLogEntryPriorityType priority);
Note there is no #Query annotation; Spring Data understands the mapping of your entity and generates the query for you based on the method name and parameter types.
This method is also more flexible; the application can use it to count all records with any of the values for priority, not just DANGER. Generally speaking, it's good to have the low-level repository methods be building blocks, like Lego. The application can then assemble a wide variety of "things" from those basic building blocks, such as a service method that counts how many DANGER log records there are.
I suggest you read all the reference docs for Spring Data repositories, starting here.

Spring Boot REST application; findBy method using foreign key

Using Spring Data REST, I have two models, NvdApps with a one-to-many relationship to NvdVulnerabilities
I'm trying to add the ability to search NvdVulnerabilities by an NvdApp, so my repository looks like this:
public interface NvdVulnerabilityRepository extends PagingAndSortingRepository<NvdVulnerability, Long> {
List<NvdVulnerability> findByNvdApp(NvdApp nvdApp);
}
And this gives me the REST end point:
"findByNvdApp" : {
"href" : "http://localhost:8080/api/nvdVulnerabilities/search/findByNvdApp{?nvdApp}",
"templated" : true
}
When I try to use this end point, it just returns the entire table, regardless of what I put in the query string. Example URL's I've tried:
http://localhost:8080/api/nvdVulnerabilities/search/findByNvdApp?nvd_app_id=25
http://localhost:8080/api/nvdVulnerabilities/search/findByNvdApp?25
http://localhost:8080/api/nvdVulnerabilities/search/findByNvdApp?NvdApp=25
Am I missing some configuration? I'm basically trying to replicate the query:
SELECT * FROM NVD_VULNERABILITY where nvd_app_id = 25
Which works as intended in the H2 database console. How exactly does the search end point work, and how do I get it to filter as intended?
I'd also like to have the paging work with the search endpoint; right now it returns the entire 7k+ rows whereas the end point http://localhost:8080/api/nvdVulnerabilities/ returns 20 items per page
You can try:
List<NvdVulnerability> findByNvdApp_Id(Integer id);
If Integer id variable exists in your NvdApp class.
Changing the repository query to match below:
public interface NvdVulnerabilityRepository extends PagingAndSortingRepository<NvdVulnerability, Long> {
Page<NvdVulnerability> findByNvdApp_Id(Long id, Pageable pageable);
}
allows searching by id as well as making the return paginated

How to get the newest record for every user using spring data mongodb?

I am struggling with a mongo query. I need to find a collection of documents in single query. The collection should contain document with newest date (field createdAt) for every user in single query.
There is a test case in Spock to demonstrate what I am trying to acheive:
def 'should filter the newest location for every user'() {
given:
List locationsInDb = [
buildLocation(USERNAME_1, '2017-02-03T10:37:30.00Z'),
buildLocation(USERNAME_1, '2017-03-04T10:37:30.00Z'),
buildLocation(USERNAME_2, '2017-02-05T10:37:30.00Z'),
buildLocation(USERNAME_2, '2017-03-06T10:37:30.00Z')
]
insertToMongo(locationsInDb)
when:
List filteredLocations = locationRepository.findLastForEveryUser()
then:
filteredLocations == [locationsInDb.get(1), locationsInDb.get(3)]
}
I found that distinct methods are a part of 2.1.0.M1 version so they are not available yet.
I was also trying with #Query annotation but the documentation (link below) does not specify how to create a query like mine.
https://docs.spring.io/spring-data/data-document/docs/current/reference/html/#d0e3309
Thanks for your help.
There are no means to express the query you are looking for via a derived query in Spring Data, nor using the MongoDB native query operators. Distinct as well will not do the job as it just extracts distinct values of a single field into an array.
Please consider using an Aggregation. Spring Data specifics can be found in the reference documentation.

Count in Spring Data MongoDB repository

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.

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