mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 07:33:17 +00:00
Add search query and create index for text columns (MySQL support)
This commit is contained in:
parent
935727dbb0
commit
846e14c036
@ -397,6 +397,26 @@ module.exports = function(strapi) {
|
||||
}, start);
|
||||
};
|
||||
|
||||
const generateIndexes = async (table, attrs) => {
|
||||
try {
|
||||
const columns = Object.keys(attributes)
|
||||
.filter(attribute => ['string', 'text'].includes(attributes[attribute].type))
|
||||
.map(attribute => `\`${attribute}\``)
|
||||
.join(',');
|
||||
|
||||
switch (definition.client) {
|
||||
case 'mysql':
|
||||
await ORM.knex.raw(`CREATE FULLTEXT INDEX SEARCH_${_.toUpper(_.snakeCase(table))} ON \`${table}\` (${columns})`);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.errno !== 1061) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!tableExist) {
|
||||
const columns = generateColumns(attributes, [`id ${definition.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY`]).join(',\n\r');
|
||||
|
||||
@ -406,9 +426,12 @@ module.exports = function(strapi) {
|
||||
${columns}
|
||||
)
|
||||
`);
|
||||
|
||||
await generateIndexes(table, attributes);
|
||||
} else {
|
||||
const columns = Object.keys(attributes);
|
||||
|
||||
await generateIndexes(table, attributes);
|
||||
// Fetch existing column
|
||||
const columnsExist = await Promise.all(columns.map(attribute =>
|
||||
ORM.knex.schema.hasColumn(table, attribute)
|
||||
|
||||
@ -46,8 +46,44 @@ module.exports = {
|
||||
.count();
|
||||
},
|
||||
|
||||
search: async function (params, populate) {
|
||||
return [];
|
||||
search: async function (params, populate, raw = false) {
|
||||
const associations = this.associations.map(x => x.alias);
|
||||
const searchText = Object.keys(this._attributes)
|
||||
.filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['string', 'type'].includes(this._attributes[attribute].type));
|
||||
|
||||
const searchNoText = Object.keys(this._attributes)
|
||||
.filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => !['string', 'type'].includes(this._attributes[attribute].type));
|
||||
|
||||
return this.query(qb => {
|
||||
// Search in columns which are not text value.
|
||||
searchNoText.forEach(attribute => {
|
||||
qb.orWhereRaw(`LOWER(${attribute}) LIKE '%${_.toLower(params.search).replace(/[^a-zA-Z. ]/g, '')}%'`);
|
||||
})
|
||||
|
||||
// Search in columns with text using index.
|
||||
switch (this.client) {
|
||||
case 'mysql':
|
||||
qb.orWhereRaw(`MATCH(${searchText.join(',')}) AGAINST(? IN BOOLEAN MODE)`, `*${params.search.replace(/[^a-zA-Z. ]/g, '')}*`);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if (params.sort) {
|
||||
qb.orderBy(params.sort.key, params.sort.order);
|
||||
}
|
||||
|
||||
if (params.skip) {
|
||||
qb.offset(_.toNumber(params.skip));
|
||||
}
|
||||
|
||||
if (params.limit) {
|
||||
qb.limit(_.toNumber(params.limit));
|
||||
}
|
||||
}).fetchAll({
|
||||
width: populate || associations
|
||||
}).then(data => raw ? data.toJSON() : data);
|
||||
},
|
||||
|
||||
countSearch: async function (params = {}) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user