I am trying to index specific fields inside of an array instead of the entire array. I have the following index:
create index `idx_aggregates` ON `ug01`
(
array
{
a.avg,
a.`start`,
a.`end`,
a.measurement
} for a in aggregates when a.measurement = 't' end
)
where (type = "aggregates" and aggregates is valued);
select meta(doc).id as docId,
array { a.avg, a.measurement} for a in aggregates end as aggs
from ug01 doc
where doc.type = 'aggregates' and doc.aggregates is valued and a.measurement = 't'
When running that query, I am getting : "No index available on keyspace ug01 that matches your query. "
If I add the entire “aggregates” array to the index, the query works, but I was trying to avoid doing that.
The index does not qualify. Index key must be present in the predicate. This is complex not sure there is easy way to do that.
CREATE INDEX `idx_aggregates` ON `ug01` (
ARRAY_LENGTH(ARRAY 1 FOR a IN aggregates WHEN a.measurement = 't' END),
ARRAY { a.avg, a.`start`, a.`end`, a.measurement } FOR a IN aggregates WHEN a.measurement = 't' END
) WHERE (type = "aggregates");
SELECT META(doc).id AS docId,
ARRAY { a.avg, a.`start`, a.`end`, a.measurement } FOR a IN doc.aggregates WHEN a.measurement = 't' END
FROM ug01 AS doc
WHERE doc.type = 'aggregates' AND
ARRAY_LENGTH(ARRAY 1 FOR a IN doc.aggregates WHEN a.measurement = 't' END) > 0;
Index selection is based on predicate you need to write predicate that can be compared to relation operator to produce bool. There is way you can do with your ARRAY key.
If you don’t want covering index you can do this.
CREATE INDEX `idx_aggregates` ON `ug01` ( DISTINCT ARRAY a.measurement FOR a IN aggregates END ) WHERE (type = "aggregates");
SELECT META(doc).id AS docId,
ARRAY { a.avg, a.`start`, a.`end`, a.measurement } FOR a IN doc.aggregates WHEN a.measurement = 't' END
FROM ug01 AS doc
WHERE doc.type = 'aggregates' AND ANY a IN doc.aggregates SATISFIES a.measurement = 't' ;
If you want you can use this approach which is more efficient. First index key will be used to index selection, 2nd index key will be used for projection and it is covered.
CREATE INDEX `idx_aggregates` ON `ug01` (
FIRST true FOR a IN aggregates WHEN a.measurement = 't' END,
ARRAY { a.avg, a.`start`, a.`end`, a.measurement } FOR a IN aggregates WHEN a.measurement = 't' END
) WHERE (type = "aggregates");
SELECT META(doc).id AS docId,
ARRAY { a.avg, a.`start`, a.`end`, a.measurement } FOR a IN doc.aggregates WHEN a.measurement = 't' END
FROM ug01 AS doc
WHERE doc.type = 'aggregates' AND
(FIRST true FOR a IN aggregates WHEN a.measurement = 't' END) == true;