How to generate dynamic query in #Query annotation from spring boot - spring

My json which stored mongodb,
{
"deviceId": "testdevice",
"deviceData": {
"device_owner": "Anand",
"device_type": "xxxx"
"device_desc": "xxxx"
...
}
}
Here deviceData is device specific.It may vary based on devices. I want to generate dynamic way to filter data based on device data , i.e, deviceData.OBJECT=VALUE. I am trying to retrieve the value from spring boot app.
My spring boot DAO class
#Query({'device':?0, 'deviceData.filterString'})
Page findByDeviceData(String deviceId, String filterString,Pageable pageable);
Can any one help how to achieve this
Thanks in advance.

Related

Custom Query REST Data with Panache

I am using REST Data with Panache for JAX RESTful Web Service generation by extending PanacheEntityResource. In Spring land there is query builder mechanism that allows the Spring Data repository to generate an SQL query based on the name and return type of the custom method signature.
I'm trying to achieve the same thing using Panache, so far unsuccessfully.
#ResourceProperties(path = "tasks", paged = false)
public interface TaskResource extends PanacheEntityResource<Task, UUID> {
List<Task> findByOrganizationId(#QueryParam("organizationId") UUID organizationId);
}
I want to pass the organazation ID as a query parameter, such that my request will be http://localhost:8080/tasks?organizationId=1e7e669d-2935-4d6f-8b23-7a2497b0f5b0, and my response will return a list of Tasks whose organization ID matches the one provided. Is there support for this functionality?
That functionality is currently not supported.
See https://quarkus.io/guides/rest-data-panache and https://quarkus.io/guides/spring-data-rest for more details

Spring Data - Using property values in projections

I have Spring Data Rest Application where I created a projection like this
#Projection(name = "UserWithAvatar", types = { User.class })
public interface UserWithAvatar {
String getName();
String getEmail();
#Value("${app.url}/pictures/#{target.imageId}")
String getAvatar();
}
The non working part is the getAvatar, it generates a url for seeing the picture.
However this ${app.url} is not working inside the projection.
How would I add this application.properties value in there?
Use #environment.getProperty('app.url') inside #{} block. It works on Spring Boot 2.3.0, i'm not sure about older versions.
Example:
#Value("#{target.pictureUrl ?: #environment.getProperty('app.url') + 'static/default-avatar.png'}")
String getAvatarUrl();

Spring Boot : Kotlin & MongoRepository : Performing a full text search

Hi there I am really new to Spring Boot and using Kotlin to learn it (I do Android/iOS professionally etc)
I have a basic API setup (Spring Boot, Web, MongoDB etc) and my interface uses MongoRepository
I have set up my MongoDB with a full-text index (text1) and sort by score. I am trying to call it in Kotlin now
override fun searchResult(search : String): List<Result> {
val criteria = TextCriteria.forDefaultLanguage()
.matchingAny(search)
val query = TextQuery.queryText(criteria)
.sortByScore()
.with(PageRequest(0, 5))
var r : List<Result> = searchRepository.findAll(query, Result.class)
}
How do I actually execute the query? FindAll is not right?
You need to create a query method in the repository interface. Please refer to repository spring documentation for details

Using $slice in Spring MongoDB Repository with #Query

I am using Spring Boot with MongoDB. In this project, I have the domain class ControlVariable, which has an array attribute named ControlVarEntries. I have been trying to use the operator $slice to get only the last five controlVarEntries of all controlVars when retrieving them in my own findAll method. This query works when tried in my Mongo client:
db.getCollection('controlVariable').find( {}, { controlVarEntries: { $slice: -5 } } )
However, I tried a similar approach in my Spring Boot project with the #Query annotation and I could not retrieve the same results. This, for instance, returns all the entries:
#Repository
public interface ControlVariableRepository extends MongoRepository<ControlVariable, String> {
#Query("{ controlVarEntries: { $slice: ?0 } }")
Page<ControlVariable> findAllLimitedNumberOfEntriesQuery(Pageable pageable, Integer numberOfEntries);
}
I would like to know if my query is wrong or if I am not using the proper syntax.
Thanks!
You have to identify the projection document in the #Query annotation.
Try
#Query(value="{}", fields = "{'controlVarEntries': { '$slice': ?0 } }")
Page<ControlVariable> findAllLimitedNumberOfEntriesQuery(Pageable pageable, Integer numberOfEntries);

Spring OAuth 2 + Spring Data Neo4j multi-tenancy

I'm going to implement multi-tenancy support in my Spring OAuth 2 + Spring Data Neo4j project.
I have configure my OAuth2 Authorization Server with a few different clients with a different clientId.
Also, I have added a base TenantEntity to my Spring Data Neo4j models:
#NodeEntity
public abstract class TenantEntity extends BaseEntity {
private String tenantId;
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
}
All of my existing Spring Data Neo4j entities must now extend this TenantEntity.
Right now I'm going to rewrite all of my Neo4j queries in order to support this tenantId parameter.
For example current query:
MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion) WHERE id(d) = {decisionId} AND NOT (c)<-[:CONTAINS]-(:CriterionGroup) RETURN c
I going to rewrite to following:
MATCH (d:Decision)<-[:DEFINED_BY]-(c:Criterion) WHERE id(d) = {decisionId} AND d.tenantId = {tenantId} AND c.tenantId = {tenantId} AND NOT (c)<-[:CONTAINS]-(:CriterionGroup) RETURN c
In turn for tenantId I'm going to use OAuth2 clientId and store it together with every Neo4j entity.
Is it a correct approach in order to implement multi-tenancy or Spring OAuth2/Data Neo4j can propose something more standard for this purpose out of the box ?
Since Neo4j currently has no feature to support multi-tenancy, if you particularly need this, it must be worked-around as you have done. You solution looks reasonable.
Alternatively, licensing is by machine, so it is possible to use, for example, Docker and spin up multiple Neo4j instances each on a different port.

Resources