This is my groovy class
Asset {
ObjectState objectState = ObjectState.CURRENT
String description
@NotEmpty(message = "*Please provide a asset name")
@Length(min = 2, max = 50, message = "*Asset name must have characters between 2 and 50")
String assetName
@DBRef
Company company
}
I want to find those assets of a particular company which contains "test" in assetName and description
Now i implemented the business logic like this
@Override
Page<Asset> fetchAssetsBySearchStringAndObjectStateAndCompany(Company company, Pageable pageable, String searchQuery) {
ObjectState objectState = ObjectState.CURRENT
if (!pageable) {
pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "lastUpdated")
}
if (searchQuery) {
Page<Asset> assets = assetRepository.findAllByCompanyAndObjectState(company, pageable, objectState)
List<Asset> filteredAssets = []
assets.each {
if (it.assetName.contains(searchQuery) || it.description.contains(searchQuery)) {
filteredAssets.add(it)
}
}
return filteredAssets // i want this list in pagination object
} else {
return assetRepository.findAllByCompanyAndObjectState(company, pageable, objectState)
}
}
I find all the assets of a company -
Filter out the "test" string using groovy closure - assets.each { }
Now my filteredAssets contains required result but i want this in pagination object
Now my question is
1- Is this approach is efficient
2- How to convert filteredAssets in Page
I also tried to use mongo native query but i am unable to convert it to spring boot
@Query('''{
'company': ?0,
$or :
[
{'assetName' : { $regex: ?1, $options:'i' }},
{'description' : { $regex: ?1, $options:'i' }},
]
}
''')
Page<Asset> findAllByCompanyAndAssetNameOrDescription(Company company, String assetName, Pageable pageable)
I don't have a specific answer but my suggestion is that your first approach is not going to work at a higher level because you are filtering the results after the pagination has been performed by the initial query. So you will potentially end up with less than the desired page size (or even an empty result) even though there are valid results that could have been returned by the query.
In other words, to achieve this you really do need to use the second approach of constructing a native query that incorporates the filtering. To resolve why that is not working, you would need to post more information about the kind of errors you are seeing (or possibly put it as a separate question and close this one out).
EDIT : to answer the question more specifically - if you choose to persist with the approach, it looks to me like you can construct your own Page
object by harnessing the Spring data PageImpl object which has a usable constructor from a list of elements. You can simply construct this object from your filtered list of elements - ie: instead of this:
...
return filteredAssets
Do this:
return new PageImpl(filteredAssets)
If you want to be more idiomatic with your groovy code I would also suggest to change the filtering operation to use findAll . In that case the code gets more compact:
return new PageImpl(assets.findAll { it.assetName.contains(searchQuery) })
Once again though I would caution that from looking at your problem I don't think it's going to have the result you actually want.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.