How can I index a text[] field in postgresql? I have two columns:

alternate_names text[]
first_name character varying


I am not sure how I can write an index on this type of query?

SELECT "people".* FROM "people" 
WHERE (lower(first_name) = 'Balzaretti' OR 'Balzaretti' ILIKE ANY (alternate_first_names));
You probably can use the citext module to query things case-insensitively.  But I would rather just impose discipline in the system to only store lower case values, and only query lowercase values. Either one would let you get rid of the 
ILIKE, which will then let you use a suitable GIN index on the array values.

This does create an annoying syntax issue, as there is no built-in operator to ask if an array contains a scalar, you have to ask if an array contains another array which just happens to hold one element.

create index on people (first_name);
create index on people using GIN (alternate_names);
select * from people where lower('Balzaretti')=first_name or
    ARRAY[lower('Balzaretti')] &amp;&amp; alternate_names;


If you don't want to specify the name twice (and avoid the BitmapOr on execution), you could combine first_name into the alternate_names list, either by changing your code to just do that, or by using an expression index:

create index on people using GIN ((alternate_names || ARRAY[first_name]));
select * from people where 
    ARRAY[lower('Balzaretti')] &amp;&amp; (alternate_names || ARRAY[first_name]);