With this schema:
create table object (
obj_id serial primary key,
name varchar(80) not null unique,
description text,
tag_arr
You can create GIN indexes on any 1-dimensional array with standard Postgres.
Details in the manual here (last chapter).
While operating with integer
arrays (plain int4
, not int2
or int8
and no NULL
values) the additional supplied module intarray provides a lot more operators and typically superior performance. Install it (once per database) with:
CREATE EXTENSION intarray;
You can create GIN or GIST indexes on integer arrays. There are examples in the manual.
CREATE EXTENSION requires PostgreSQL 9.1 or later. For older versions you need to run the supplied script.
This is my workaround, because I see no PostgreSQL optimized internal function for do the same,
CREATE FUNCTION unnest_with_idx(anyarray) RETURNS
table(idx integer, val anyelement) AS $$
SELECT generate_series(1,array_upper($1,1)) as idx, unnest($1) as val;
$$ LANGUAGE SQL IMMUTABLE;
-- Test:
SELECT idx,val from unnest_with_idx(array[1,20,3,5]) as t;
For check if exists an internal function, see "How to acess array internal index with postgreSQL?" question.
Edited after @JimNasby comment
SELECT * FROM unnest(array[20,11,3,5]) WITH ORDINALITY;
the WITH ORDINALITY
produces a new column "ordinality" that is the array-index. See also this tutorial.
In pg9.5+, it works fine also for JSON arrays!
SELECT * FROM jsonb_array_elements( '[20,11,3,5]'::JSONB ) WITH ORDINALITY
The traditional solution would be to use a table of tags and a many-many between tag and object. Then you can index the tag table and pull everything in a single select statement via a join. If you're not happy with the programming model, check out your local friendly ORM vendor.
I'm not a PostgreSQL expert by any means, but this doesn't seem like a good use case for arrays.