Как получить первый или последний элемент из cqengine IndexedCollection с помощью NavigableIndex

У меня есть объект com.googlecode.cqengine.IndexedCollection с настроенным NavigableIndex. Мне нужно получить первый или последний элемент из индекса или итератора индекса в целом.

Я полагаю, это должно быть тривиально. Я знаю, что могу создать объект Query с объектом queryOptions, использовать его для извлечения итератора из IndexedCollection и получения первого объекта, но я не уверен, что это оптимально для производительности. Конечно, это не элегантно.


person Pavel Niedoba    schedule 12.07.2018    source источник


Ответы (4)


С помощью miradham я разобрался, что нужно запоминать индексы, так как сложно подобрать нужный, если их больше. Это будет работать только с NavigableIndex, мы не можем повторять базовый класс Index

collection = new ConcurrentIndexedCollection<Data>();
index = NavigableIndex.onAttribute(Data.UNIQUE_TIMESTAMP);
collection.addIndex(index);

когда у меня есть индекс:

try (CloseableIterator<KeyValue<String, Data>> iterator = indexUniqueTimestamp.getKeysAndValuesDescending(null).iterator()) {
        if (iterator.hasNext())
            return iterator.next().getValue();
    }
    return null;
person Pavel Niedoba    schedule 24.07.2018

Один из приемов получения минимального или максимального (то есть первого или последнего) объекта в соответствии с одним из его атрибутов — использовать all() (который соответствует всем объектам в коллекции), и чтобы запросить результаты, которые должны быть возвращены в порядке возрастания или убывания вашего атрибута.

Например, если у вас есть коллекция объектов Car, вы можете использовать следующий код для получения автомобиля с самой высокой (т. е. максимальной) ценой:

try (ResultSet<Car> results = cars.retrieve(
    all(Car.class),
    queryOptions(
        orderBy(descending(Car.PRICE)),
        applyThresholds(
            threshold(INDEX_ORDERING_SELECTIVITY, 1.0)
        )
    ))) {

    results.stream()
        .limit(1)
        .forEach(System.out::println);
}

Вы также можете изменить ограничение на значение, отличное от 1, если вы хотите, чтобы были возвращены первые n самых дорогих автомобилей.

Приведенный выше код будет работать независимо от того, действительно ли у вас есть NavigableIndex в цене. Немного об INDEX_ORDERING_SELECTIVITY заключается в том, чтобы фактически запросить CQEngine для использования индекса (подробнее здесь).

person npgall    schedule 06.12.2018

или итератор индекса вообще

Вы можете использовать getIndexes() API Интерфейс QueryEngine для получения набора индексов.

Пример кода:

IndexedCollection<Car> indexedCollection = new ConcurrentIndexedCollection<Car>();
indexedCollection.addIndex(HashIndex.onAttribute(Car.CAR_ID), noQueryOptions());

List<Index<Car>> indexes = new ArrayList<Index<Car>>();
for (Index<Car> index : indexedCollection.getIndexes()) {
    indexes.add(index);
}
person miradham    schedule 16.07.2018

NavigableIndex хранит объект в элементе на карте с атрибутом в качестве ключа и набором объектов в качестве значения.

NavigableIndex не поддерживает порядок вставки. Первым элементом индекса может быть что угодно.

CQEngine лучше всего разработан для произвольного доступа к объекту в коллекции, а не для последовательного доступа.

Обычные коллекции в java лучше всего подходят для последовательного доступа с индексом.

один элегантный способ доступа к первому элементу — создать класс SequentialIndex и добавить его в параллельную коллекцию. получить элемент, используя индекс в качестве запроса.

person Ramanathan Ganesan    schedule 24.07.2018
comment
Индекс поддерживает порядок, заданный компаратором, поэтому первый не может быть ничем иным, как наименьшим. Я не могу найти SequentialIndex в библиотеке CQEngine. - person Pavel Niedoba; 24.07.2018