Q:

Postgresql - order by number of matches in array

I'm trying to get a list of the best matching items giving a list of tags.
With the data below:
DROP TABLE IF EXISTS testing_items;
CREATE TEMP TABLE testing_items(
    id bigserial primary key,
    tags text[]
);
CREATE INDEX ON testing_items using gin (tags);

INSERT INTO testing_items (tags) VALUES ('{123,456, abc}');
INSERT INTO testing_items (tags) VALUES ('{222,333}');
INSERT INTO testing_items (tags) VALUES ('{222,555}');
INSERT INTO testing_items (tags) VALUES ('{222,123}');
INSERT INTO testing_items (tags) VALUES ('{222,123,555,666}');

I have the tags 222,555 and 666. How can I get a list like this?
ps: GIN index must be used because there will be tons of records.
id         matches
--         -------
5          3
3          2
2          1
4          1

Edit
Id 1 should not be in the list because doesn't match any tag
1          0

A:

Unnest tags, filter unnested elements and aggregate remaining ones:
select id, count(distinct u) as matches
from (
    select id, u
    from testing_items,
    lateral unnest(tags) u
    where u in ('222', '555', '666')
    ) s
group by 1
order by 2 desc

 id | matches 
----+---------
  5 |       3
  3 |       2
  2 |       1
  4 |       1
(4 rows)

Considering all the answers, it seems that this query combines good sides of each of them:
select id, count(*) 
from testing_items,
unnest(array['11','5','8']) u
where tags @> array[u] 
group by id 
order by 2 desc, 1;

It has the best performance in Eduardo's test.

