In Elasticsearch, I have an index with the following mapping (simplified):
{
"properties": {
"@timestamp": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"
},
"eventId": {
"type": "keyword",
"null_value": "NULL"
},
"statuses": {
"type": "nested",
"properties": {
"message": {
"type": "keyword",
"null_value": "NULL"
},
"status": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
}
Let’s assume that we have the following data in the index:
eventId | statuses.message | statuses.status |
---|---|---|
ID1 | M1, M2 | INFO, ERROR |
ID2 | M2, M4 | OK, INFO |
ID3 | M5 | INFO |
I would like to make a query using the Criteria API that will search by eventId
, statuses.message
, and statuses.status
fields. But for the last two fields, the appropriate documents should be returned only in the case when the query finds a document with both required values in the same object in the collection.
So, for the query
eventId: ID1 and [M1] in statuses.message and statuses.status: INFO
there should be a match. But for the query:
eventId: ID1 and [M2] in statuses.message and statuses.status: INFO
should not return any value, because there isn’t an object in statuses
that have message: M2
and status: INFO
.
I’ve created the following query but it doesn’t work quite as intended:
var criteria = new Criteria();
criteria.and(new Criteria(EVENT_ID.getLabel()).is(request.getEventId()));
Criteria subCriteria = new Criteria()
.and(STATUSES_MESSAGE.getLabel()).in(request.getMessageCodes())
.and(STATUSES_STATUS.getLabel()).is(request.getStatus());
criteria.subCriteria(subCriteria);
var criteriaQuery = new CriteriaQuery(criteria);
This approach returns the document with eventId: ID1
and the intention here is to return no value.
Is there a way to implement described behavior using the Criteria API? If not, which approach should be chosen otherwise?