Adding Solr sort criteria to named query in Spring Data - spring

I am trying to add a sort criteria to a Spring data Solr search.
I have seen methods for sorting search results (List<> .. after the data has been received from Solr) but not for specifying the sort order to Solr in the query.
The Solr query should look like....
http://localhost:8088/solr/books/select?fl=fullrecord%2C%20url&q=mod_date%3A%5B2012-04-17T11%3A38%3A15Z%20TO%20NOW%5D&sort=mod_date%20asc
I need to do this in Solr because the request is paged (there are potentially hundreds of thousands of results) and so only a limited number of results (one page) are returned for each query.
How can I add the "&sort=mod_date asc" solr query string?
// Catalog.findByDateChanged=mod_date:[?0 TO ?1]
public interface CatalogRepository extends SolrCrudRepository<CatalogDoc, String> {
#Query(name = "Catalog.findByDateChanged", fields = { "fullrecord", "url" })
public Page<CatalogDoc> findByDateChanged(String fromDate, String toDate, Pageable pageable);
}

It seem that the sort can be added to the call...
Page<CatalogDoc> results = solrRepo.findByDateChanged(from, to,
PageRequest.of(pageNo, perPage, Sort.Direction.ASC, "mod_date" ));
Curiously it adds it twice to the command to Solr...
&sort=mod_date+asc,mod_date+asc

Related

Stream MongoDB Result of FindAll documents

I want to write a mongo query to fetch All Documents in a collection and project just 2 fields and no criteria.
I want to use streams here and iterate over the list of documents to process them.
How can I write this in Java Spring Mongo?
I have something like this:
public CloseableIterator<Employees> streamAllEmployees() {
Query query = new Query();
query.fields().include("_id.name","_id.dept");
query.addCriteria(Criteria.where("_id.dept").is(1));
return mongoOperations.stream(query, Employee.class);
}
but how can I change this to not have any QueryCriteria?

SpringData ElasticSearch insert/update multiple documents

My goal is to do insert and update multiple documents in ElasticSearch using ElasticsearchRepository.
public interface EmployeeInfoRepository extends ElasticsearchRepository<EmployeeInfo, String> {
}
However, whenever I call saveAll(entities), the number of document is unchanged but it creates new indexes for those entities.
employeeInfoRepository.saveAll(employeeInfos);
If I insert 1000 elements, at first it will have 1000 docs and 1000 indexes, which is what I expected. Then I call saveAll two more times, it still has 1000 docs but now the number of indexes increases to 3000.
How can I update it properly?
It would be the best if it's just as easy as calling saveAll and the rest is handled by SpringBootData ElasticSearch.
Update 1:
There is no change with the data, however when I run saveAll, the storage_size keeps increasing. Not sure if it creates the indexes again and still keeps the old indexes.
If you define the id in your document class, elasticsearch updates/inserts the document with the same document id value.
Here an example:
#Document(indexName = "example_index")
public class Example {
#Id
#Field(type = FieldType.Long)
private long id;
}
Of course, you have to handle the logic for a unique id in your project.

Spring Data find substring containing special characters

How to retrieve data from elasticsearch containing special characters like . / - ... using spring data ?
I have document defined like this:
#Document(indexName = "audit-2018.135", type = "audit")
public class Trace {
#Id
private String id;
#Field(type = FieldType.Text)
private String uri;
// setters & getters
}
I need to retrieve data from elasticSearch by field uri.
Here's an example how data looks:
martin-int-vip.vs.cz:5080/kib/api/runtime/case/CASE0000000000324223
When using kibana I can use:
uri: "martin-int-vip.vs.cz:5080/kib"
and I get back the record above which contains desired substring.
Now I need to achieve the same from java however in spring data it's not working as expected.
I have elasticSearchRepository defined like this:
public interface TraceRepository extends ElasticsearchRepository<Trace, String> {
List<Trace> findByUriContaining(String uri);
}
when I call method findByUriContaining with parameter uri as:
martin-int-vip.vs.cz:5080\/kib
or even this
martin-int
I get back 0 results. When I send "kib" as parameter it returns correctly all records containing word "kib" however it's not working with special characters like . / - etc. How should I query my elasticSearch from java to get all records which contains my desired substring ? Thanks
I found out that by default elasticSearch analyzer tokenize your query. Instead of "martin-int-vip.vs.cz:5080/kib" it looks for a field which contains martin and int and vip...
In order to query these kind of fields you need to change behaviour of analyzer or you can use elasticSearchTemplate and Criteria to build more flexible queries.

Group toghether Node properties and return as a view in Cypher

I am working with v2.2.3 of Neo4J and Spring Neo4j Data SDN 4
I want to return a few properties of a node using a cypher query and map them into attributes of a POJO.My function in Spring data repository looks something like this
#Query(
"MATCH(n:ServiceProvider{profileStatus:{pStatus},currentResidenceState:{location}}) RETURN n.name,n.currentResidenceAddress ,n.employmentStatus,"
+ "n.idProofType,n.idProofNumber
ORDER BY n.registrationDate DESC SKIP{skip} LIMIT {limit}")
List<AdminSearchMapResult> getServiceProviderRecords(
#Param("pStatus")String pStatus,
#Param("location")String location,
#Param("skip") int skip,#Param("limit")int limit);
I get an error like
Scalar response queries must only return one column. Make sure your cypher query only returns one item.
I think its because of the fact that I cant bundle all the returned attributes into a view that can map into the POJO
If I return the node itself and map it into a POJO it works
Kindly guide
This can be done using #QueryResult
Annotate the AdminSearchMapResult POJO with #QueryResult. For example:
#QueryResult
public class AdminSearchMapResult {
String name;
String currentResidenceAddress;
...
}
Optionally annotate properties with #Property(name = "n.idProofType") if the alias is different from the field name.

Order By property from dynamic linq

I am using dynamic linq to make a generic class for processing a generic JqGrid from MVC all works fine (searching, pagination etc) except for sorting on code properties. Sorting works fine when I am hitting the DB to sort the data, but as soon as it is a property I have made the sorting does not work eg
public partial class tblStockOrder
{
public string approved
{
get
{
return approved_id == null ? "" : "Approved";
}
}
}
I am running the following Dynamic Linq
items = items
.OrderBy(string.Format("{0} {1}", sidx, sord))
.Skip(pageIndex * pageSize)
.Take(pageSize);
Where sidx etc are strings passed in by jquery.
So basically what is the best solution for handling a case where some properties will be from the db while others will be code properties (not sure of the correct naming). I can handle all this in code using reflection but would obviously like the DB to handle as much of the searching / sorting as possible without pulling in thousands of records and sorting through them in code using reflection.
Computed class will of course not work, as you're trying to create record which is part in memory, part in database.
You can, however, compute the same on database by specifying the function in linq query, example:
items = items
.OrderBy(x=> x.approved_id != null )
.Skip(pageIndex * pageSize)
.Take(pageSize);

Resources