I have the following Document (... means more properties and getters and setters)
@Document
public class Equipment
{
...
private String name;
private String internalManufacturer;
private String externalManufacturer;
...
}
And this method in a service, where the name of field is passed (code) and the sorting is set.
private void setSorting(String code)
{
...
List<AggregationOperation> pagedAndSortedQuery= new ArrayList<>(baseQuery);
SortOperation sortOperation = sort(Sort.Direction.ASC, code);
if (EquipmentsSortingField.MANUFACTURER.getCode().equals(code))
{
sortOperation = sort(sortingDirection, "internalManufacturer", "externalManufacturer");
pagedAndSortedQuery.add(sortOperation);
}
}
I want to sort internalManufacturer and externalManufacturer as if they were one field, because if I do it as in the service, first I get the result sorted internalManufacturers and them sorted externalManufacturers. Important, if externalManufacturer is empty, internalManufacturer is not and viceversa.
For example, I have this in database:
Equipment (externalManufacturer: John, internalManufacturer: null)
Equipment (externalManufacturer: null, internalManufacturer: Carlos)
Equipment (externalManufacturer: Ash, internalManufacturer: null)
Equipment (externalManufacturer: null, internalManufacturer: Victor)
With my code I get the equipments sorted like this:
Equipment (externalManufacturer: null, internalManufacturer: Carlos)
Equipment (externalManufacturer: null, internalManufacturer: Victor)
Equipment (externalManufacturer: Ash, internalManufacturer: null)
Equipment (externalManufacturer: John, internalManufacturer: null)
And I like to get them like this:
Equipment (externalManufacturer: Ash, internalManufacturer: null)
Equipment (externalManufacturer: null, internalManufacturer: Carlos)
Equipment (externalManufacturer: John, internalManufacturer: null)
Equipment (externalManufacturer: null, internalManufacturer: Victor)
In summary, sort both fields as if it was only one field.
How can I do that? Thanks in advance.
You should generate a new field using $addFields
, which is the concatenated version of the internal and external manufacturer. Then use this new field for sorting. Something along these lines:
private void setSorting(String code)
{
...
List<AggregationOperation> pagedAndSortedQuery= new ArrayList<>(baseQuery);
SortOperation sortOperation = sort(Sort.Direction.ASC, code);
if (EquipmentsSortingField.MANUFACTURER.getCode().equals(code))
{
AddFieldsOperation addFieldsOperation =
Aggregation.addFields().addFieldWithValue(
"manufacturerString",
StringOperators.Concat.valueOf(ConditionalOperators.ifNull("internalManufacturer").then("")).concatValueOf(ConditionalOperators.ifNull("externalManufacturer").then(""))
).build();
sortOperation = sort(sortingDirection, "manufacturerString");
pagedAnsSortedQuery.add(addFieldsOperation);
pagedAndSortedQuery.add(sortOperation);
}
}
Note that I have used the new field for sorting, and also added the addField
stage to the pipeline. Please test it out, I hope you get the idea.