Я использовал некоторый шаблонный код (ниже), который создает нормализованный столбец tsvector _search
всех указанных мной столбцов (в searchObjects
), для которых требуется полнотекстовый поиск.
Для По большей части это нормально. Я использую это в сочетании с Sequelize, поэтому мой запрос выглядит следующим образом:
const articles = await Article.findAndCountAll({
where: {
[Sequelize.Op.and]: Sequelize.fn(
'article._search @@ plainto_tsquery',
'english',
Sequelize.literal(':query')
),
[Sequelize.Op.and]: { status: STATUS_TYPE_ACTIVE }
},
replacements: { query: q }
});
Настройка индекса поиска:
const vectorName = '_search';
const searchObjects = {
articles: ['headline', 'cleaned_body', 'summary'],
brands: ['name', 'cleaned_about'],
products: ['name', 'cleaned_description']
};
module.exports = {
up: async queryInterface =>
await queryInterface.sequelize.transaction(t =>
Promise.all(
Object.keys(searchObjects).map(table =>
queryInterface.sequelize
.query(
`
ALTER TABLE ${table} ADD COLUMN ${vectorName} TSVECTOR;
`,
{ transaction: t }
)
.then(() =>
queryInterface.sequelize.query(
`
UPDATE ${table} SET ${vectorName} = to_tsvector('english', ${searchObjects[
table
].join(" || ' ' || ")});
`,
{ transaction: t }
)
)
.then(() =>
queryInterface.sequelize.query(
`
CREATE INDEX ${table}_search ON ${table} USING gin(${vectorName});
`,
{ transaction: t }
)
)
.then(() =>
queryInterface.sequelize.query(
`
CREATE TRIGGER ${table}_vector_update
BEFORE INSERT OR UPDATE ON ${table}
FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(${vectorName}, 'pg_catalog.english', ${searchObjects[
table
].join(', ')});
`,
{ transaction: t }
)
)
.error(console.log)
)
)
),
down: async queryInterface =>
await queryInterface.sequelize.transaction(t =>
Promise.all(
Object.keys(searchObjects).map(table =>
queryInterface.sequelize
.query(
`
DROP TRIGGER ${table}_vector_update ON ${table};
`,
{ transaction: t }
)
.then(() =>
queryInterface.sequelize.query(
`
DROP INDEX ${table}_search;
`,
{ transaction: t }
)
)
.then(() =>
queryInterface.sequelize.query(
`
ALTER TABLE ${table} DROP COLUMN ${vectorName};
`,
{ transaction: t }
)
)
)
)
)
};
Проблема заключается в том, что код объединяет оба столбца в каждом В массиве searchObjects
хранится объединенный индекс всех столбцов в каждом массиве.
Например, в таблице articles
: 'headline', 'cleaned_body', 'summary'
являются частью этого единственного сгенерированного вектора _search
.
Из-за этого я не могу выполнять поиск ТОЛЬКО headline
или ТОЛЬКО cleaned_body
и т. Д. c. Я хотел бы иметь возможность искать каждый столбец как отдельно, так и вместе.
Вариант использования находится в моем поиске, я хочу искать только по заголовку. Но на моей странице результатов поиска я хочу выполнить поиск по всем столбцам, указанным в searchObjects
.
Может кто-нибудь дать мне подсказку о том, что мне нужно изменить? Должен ли я создать новый tsvector для каждого столбца?