如何使用 NavigableIndex 从 cqengine IndexedCollection 获取第一个或最后一个项目

How to get first or last item from cqengine IndexedCollection with NavigableIndex

我有 com.googlecode.cqengine.IndexedCollection 个配置了 NavigableIndex 的对象。一般来说,我需要从索引或索引的迭代器中获取第一项或最后一项。

我想这应该是微不足道的。我知道我可以使用 queryOptions 对象创建 Query 对象,使用它从 IndexedCollection 中检索迭代器并获取第一个对象,但我不确定它是否是性能最佳的。果然不优雅。

or iterator of the index in general

您可以使用 getIndexes() API 或 QueryEngine interface 检索索引集。

示例代码:

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);
}

在 miradham 的帮助下,我发现我需要记住索引,因为如果我们有更多索引,就很难找到正确的索引。它只适用于 NavigableIndex,我们不能迭代基础 class 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;

NavigableIndex 将对象存储在 Map 中的元素中,以属性为键,对象集为值。

NavigableIndex 不维护插入顺序。索引的第一个元素可以是任何东西。

CQEngine 最适合随机访问集合中的对象而不是顺序访问。

java 中的普通集合最适合使用索引进行序列访问。

访问第一个元素的一种优雅方法是创建 SequentialIndex class 并将其添加到并发集合中。使用索引作为查询检索元素。

根据其中一个属性检索最小或最大(即第一个或最后一个)对象的一个​​技巧是使用 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 利用索引(更多细节 here)。