Допустим, у нас есть таблица PostgreSQL contacts
, каждая запись имеет набор помеченных адресов электронной почты (пары меток и электронных писем) & mdash; один из которых является «основным».
Это хранится как:
id
первичный ключ
email
текст
email_label
текст
metadata
JSONB
emails
массив
email
текст
label
текст
Например, запись может выглядеть примерно так:
id: 1
email: 'a@a.com'
email_label: 'a'
metadata: {
"emails": [
{
"email": "b@b.com",
"label": "b"
},
{
"email": "c@c.com",
"label": "c"
}
]
}
Учитывая этот шаблон хранения, мы хотим иметь возможность найти запись по любому из ее адресов электронной почты.
Наивный запрос будет выглядеть так:
SELECT id
FROM contacts
WHERE
email = 'my@email.com' OR
metadata -> 'emails' @> '[{"email": "my@email.com"}]'
Есть ли способ создать индекс, который значительно ускоряет эту операцию? Потребуется автоматическое обновление в ответ на изменения записей и в идеале индексирование как по текстовому столбцу, так и по вложенному JSONB колонка.
В этом конкретном случае использования можно было бы эффективно и быстро выполнять поиск по адресу электронной почты, не изменяя эту структуру и не создавая новую реляционную таблицу.
Я полагаю, что решение предполагает использование индекса GIN, а в этом вопросе упоминается jsonb_path_ops , но я не уверен, как свести все кусочки вместе.