Skip to main content
ElastiCORE 3.0 is a release candidate: 3.0.261022-rc1 on Maven Central. Projects on the 2.2 line: see the 2.2 documentation.
Version: 3.0

Search and sorting

Every @expose entity gets a search DTO (XxxSrchDTO) and POST /api/<domain>/<entity>/search. A field's @search(condition) decides how it is searched (@s, @srch and @filter are the same); a second value after a comma names the entity field (@search(like,comName)).

POST /api/shop/product/search
{ "name": "fish", "pageNumber": 0, "pageSize": 20, "sortCode": "name+" }

The answer is a page: content, totalElements, totalPages, number. pageNumber starts at 0.

Conditions​

DSLCriteriaIgnores caseMeans
eq, =equalnoexact match
likelike (%v%)v3: yes / 2.x-compatible: nopart of the value
%_%, %%like (%v%)nopart of the value, case kept - every mode
%__%like (%v%)yespart of the value, case ignored
__=, =__equalyesexact, case ignored
_% / %_like (v% / %v)nostarts with / ends with
__% / %__likeyesstarts with / ends with, case ignored
>, >=, <, <=comparisonsno
in.in()noone of several values (status: List<Status> @search(in))
between, ~betweenno<field>From and <field>To
isnullisNull / isNotNullnoempty or not: a <field>Empty: Boolean property (v3 bundles)
auto (@search alone)decided at run timenotext only: like when the value starts or ends with %, otherwise eq
like ignores case in v3

In v3 mode - hexagonal, DDD, -Pv3, every Kotlin build - @search(like) on a text field is the same as %__%: the value is trimmed and lower-cased (Locale.ROOT), the column compared with lower(...). {"name":"gold"} finds Goldfish. Layered Java's 2.x-compatible output keeps case. To keep case on v3, write @search(%_%).

  • A % or _ the caller puts in the value stays a wildcard ({"name":"%Puppy%"}).
  • Not implemented: !=, neq, the keywords gt, gte, lt, lte, ilike. An unknown condition searches by equality; v3 warns ... is not a search condition, so it searches by equality.
  • Without @search, an @expose entity's text fields get auto, date and time fields between, other types eq.
  • between on a LocalDate adds a day to To, so the last day is included.

isnull - is the value empty?​

Loan:
fields:
returnedDate: date @readonly @search(isnull) -- returned on, empty until returned
returnedDateEmpty in the requestCondition
not sent, or nullnone
trueIS NULL - loans not yet returned
falseIS NOT NULL

One condition per field: an isnull field gets no From/To. With @ref(order.shippedDate) the column across the reference is checked. The 2.x generator and the jpa-springboot output treat isnull as an unknown condition (equality).

A list field​

drivers: List<RentDriver> @search(eq) gives driversItem and a join (root.join("drivers")); @search(in) on a list field joins too.

Across a reference​

companyName: string @search(like) @ref(company.name)    # r.get("company").get("name")

Default order: @sort​

entity:
Product:
meta: entity @root @expose(20) @sort(name+)
PurchaseOrder:
meta: entity @root @expose(20) @sort(orderDate-, orderId-)

The order a search takes when the request sends no sortCode - on the entity for all its search DTOs, or on a search DTO for that one (the search DTO's wins). The request's sortCode always wins. Generated: @Builder.Default private String sortCode="name+";. Without @sort a search has no order.

Searching in code​

Generated code builds a Specification from the search DTO. In your own code the Q class builds conditions at run time, with operators the DSL does not have:

Specification<VendorInfo> spec = Q.VendorInfo.vendorName(Op.ILIKE, "acme");
// WHERE LOWER(vendor_name) LIKE LOWER('%acme%')

Op: EQ, NEQ, LIKE (case kept), ILIKE, NOT_LIKE, STARTS_WITH, ENDS_WITH, NOT_ILIKE, ISTARTS_WITH, IENDS_WITH, IEQ, GT, GTE, LT, LTE, IN, NOT_IN, IS_NULL, IS_NOT_NULL, BETWEEN. JoinSpec, UpdateSpec and DeleteSpec build joins, bulk updates and deletes from the same Q metadata; see blueprint/elasticore-dev-guide.md.