2

I have curent method in my repository :

List<Record> getSortedByDate(int limit, int lastId){ 

    FullTextSession fullTextSession = fullTextSession();
    QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Record.class).get();
    // some extra matching

    FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(finalQuery, Record.class);
    fullTextQuery.setMaxResults(limit);
    fullTextQuery.setSort(new Sort(new SortField("created", SortField.Type.LONG, false)));

    // ??? here I have to restrict results to include all records with id
    // which is after lastId in context of current sort

    return fullTextQuery.list(); 
}

And I have current entity:

@Entity
@Indexed
public class Record{

    @Id
    @GeneratedValue
    private int id;

    @Field
    @SortableField
    @DateBridge(resolution = DAY)
    private Date created;

    ***
}

I'm sorting my search results using "created" field:

I need to return only that objects, which are after object with given "id" field value in context of this sorting. For example, if i have 3 records in index:

{"id": 3, "created": "27.04.13"},
{"id": 1, "created": "29.04.15"},
{"id": 4, "created": "7.10.15"}

and my method receives lastId 1 it must return last record only.

I need to do this because I have to implement proper pagination with sorting.

UPDATE Also, in future i need to implement sorting not only by date, but by other fields, such as rating (integer) and reviewsCount (integer), so limiting results by range may not be a solution since several records may have same rating or same reviewsCount.

UPDATE 2 I've combined answer from @Gunnar with this kind of filtering, seems like it works.

Date limitValue = session().get(Record.class, lastId).getCreated();
mainJunction.must(queryBuilder.range().onField("created").above(limitValue).createQuery());
mainJunction.must(queryBuilder.phrase().onField("id").sentence(String.valueOf(lastId)).createQuery()).not();

..where session() is a Hibernate DB session. And now I can safely use rating or reviewsCount sorting.

Taras
  • 507
  • 1
  • 6
  • 17

1 Answers1

2

You could load the Record with the given id and then restrict your query results to records created after that date:

Record lastRecord = ...;

QueryBuilder queryBuilder = fullTextSession
    .getSearchFactory()
    .buildQueryBuilder()
    .forEntity(Record.class).get();

Query query = queryBuilder.range()
    .onField( "created" )
    .above( lastRecord.getCreated() )
    .createQuery();

FullTextQuery fullTextQuery = fulllTextSession.createFullTextQuery(
    query, Record.class
);

You only might have to choose a finer date resolution than DAY in order to get the sorting right when wrapping pages within several records created on the same day.

Gunnar
  • 18,095
  • 1
  • 53
  • 73
  • Thank you very much for you response, but anyway is possible the case with same dates (if records were added programmatically and almost simultaneously). Also, see my question's update. I will be grateful for your advice how to handle that case. – Taras Dec 22 '15 at 11:40
  • Do you mean sorting first by date, then by rating etc. (i.e. one sort containing several fields)? Or sorting y date *or* by rating *or* by review rating etc.? – Gunnar Dec 22 '15 at 14:57
  • By date or by rating or by reviewsCount. Currently I've found some solution, I've combined your answer with excluding Record which id is lastId. See update. – Taras Dec 22 '15 at 15:46
  • But I don't know if it's the best way to do this. – Taras Dec 22 '15 at 16:00