Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

  1. Introduce new type of query - INDEX;
  2. Final query processing is performed within IndexQueryProcessor;
  3. Entrypoint for distributed index queries is the IndexQueryProcessor.queryDistributed method, that leverage on other cache queries (ScanQuery, TextQuery):
    1. the Map phase is node-local querying of index, it returns sorted data by definition;
    2. filtering with IndexQuery.setFilter is analogue of ScanQuery.setFilter;
    3. the Reduce phase is responsible for the Merge Sort of data from multiple nodes;
  4. Entrypoint for local query is the IndexQueryProcessor.queryLocal method. It accepts users IndexQueryand IndexingQueryFilter for filtering result cache entries (primary partition, MVCC, etc).


Rules to write criteria:

  1. Order of field in criteria doesn't matter.
  2. Fields can be used any times, Ignite uses AND to build final index range.


Rules to choose index:

  1. If index name specified - then get index with this name and check that criteria fields match it.
  2. If index name isn't specified - then find index that matches all specified criteria fields. Fields have to be prefix of an index.


Code Block
languagejava
// Internal
Code Block
languagejava
// Internal package.

public class IndexQueryProcessor extends GridProcessorAdapter {
	// Provides access to indexes.
	private final IndexProcessor processor;

	// Entrypoint for local query.
    public Iterator<Cache.Entry<?,?>> queryLocal(IndexQuery idxQuery, @Nullable IndexingQueryFilter filters) throws IgniteException {
		// 1. If user specified index name, then check a query:
		// - sort query fields in index key order;
		// - check that it's a valid index query: fields covers index keys (from left to right)
		// - fail otherwise.
		// 2. If user doesn't specified index name:
		// - get all indexes for specified cache and Value.class;
		// - find index by filtering by a query fields (index keys must be in the same order as specified query fields, try sort fields to match any index).
		// - validate index query (see validation steps from 1.)
		Index idx = index(idxQuery.desc());

		// 1. Parse index conditions.
		// 2. Validate index condition, index type.
		// 3. Maps index conditions to an index query methods.
		// 4. Perform index operations, get Cursor.
		GridCursor<IndexRow> cursor = query(idx, idxQry.conditions());

		// 1. Map IndexRow to Cache entry.
		// 2. Apply specified cache filters (primary partitions, MVCC versions, etc.)
		// 3. Wrap cursor to iterator and return.
		return map_and_filter(cursor, filters);
	}

	private GridCursor<IndexRow> query(Index idx, List<IndexCondition> conditions) {
		// eq(key) -> idx.findOne(key)
		// notEq(key) -> idx.find(null, null, current -> current != key)
		// gt(key) -> idx.find(key, null, current -> current != key)
		// gte(key) -> idx.find(key, null)
		// lt(key) -> idx.find(null, key, current -> current != key)
		// lte(key) -> idx.find(null, key)
		// between(left, right) -> idx.find(left, right), inclusive only
		// in(keys...) -> idx.findOne(keys[0]) && idx.findOne(keys[1]) ...
		// notIn(keys...) -> idx.find(null, null, current -> !keys.contains(current))
		// min() -> idx.findFirst()
		// max() -> idx.findLast()
		// predicate(p) -> idx.find(null, null, p)
	}
}

...

  1. index conditions joint with OR;
  2. different sort order: idx(ts desc, price asc) but query(ts desc, price desc);
  3. Cache is wide and IndexScan on few fields is much cheaper than ScanQuery;
  4. predicatesetFilter operation with a custom user condition.


IndexName is optional. If it's not specified than take PK index of specified table.


Code Block
languagejava
// The "predicate" operation can't find best index for a user query. So user must provide an index name for this operation. 
QueryCursor<Cache.Entry<Long, Good>> cursor = ignite.cache("GOOD").query(
	new IndexQuery<>("GOOD_TBL", "GOOD_TS_DESC_PRICE_ASC_IDX")
		.predicatesetFilter((good) -> good.ts > lastMidnightTs || price > 100)
);

...