mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +00:00
Fix deepFiltering with draft & publish
Signed-off-by: Convly <jean-sebastien.herbaux@epitech.eu>
This commit is contained in:
parent
fad9fda318
commit
03f5342123
@ -13,7 +13,7 @@ const BOOLEAN_OPERATORS = ['or'];
|
||||
const buildQuery = ({ model, filters }) => qb => {
|
||||
if (_.has(filters, 'where') && Array.isArray(filters.where) && filters.where.length > 0) {
|
||||
qb.distinct();
|
||||
buildJoinsAndFilter(qb, model, filters.where);
|
||||
buildJoinsAndFilter(qb, model, filters);
|
||||
}
|
||||
|
||||
if (_.has(filters, 'sort')) {
|
||||
@ -45,9 +45,11 @@ const buildQuery = ({ model, filters }) => qb => {
|
||||
* Add joins and where filters
|
||||
* @param {Object} qb - knex query builder
|
||||
* @param {Object} model - Bookshelf model
|
||||
* @param {Array<Object>} whereClauses - an array of where clause
|
||||
* @param {Object} filters - The query filters
|
||||
*/
|
||||
const buildJoinsAndFilter = (qb, model, whereClauses) => {
|
||||
const buildJoinsAndFilter = (qb, model, filters) => {
|
||||
const { where: whereClauses } = filters;
|
||||
|
||||
/**
|
||||
* Returns an alias for a name (simple incremental alias name)
|
||||
* @param {string} name - name to alias
|
||||
@ -210,12 +212,29 @@ const buildJoinsAndFilter = (qb, model, whereClauses) => {
|
||||
});
|
||||
};
|
||||
|
||||
const aliasedWhereClauses = buildWhereClauses(whereClauses, { model });
|
||||
/**
|
||||
* Add queries on tree's joins (deep search) based on given filters
|
||||
* @param tree - joins tree
|
||||
*/
|
||||
const addFiltersQueriesToJoinTree = tree => {
|
||||
_.each(tree.joins, value => {
|
||||
const { alias, model } = value;
|
||||
|
||||
buildJoinsFromTree(qb, tree);
|
||||
runPopulateQueries(
|
||||
toQueries({
|
||||
publicationState: { query: filters.publicationState, model, alias },
|
||||
}),
|
||||
qb
|
||||
);
|
||||
addFiltersQueriesToJoinTree(value);
|
||||
});
|
||||
};
|
||||
|
||||
const aliasedWhereClauses = buildWhereClauses(whereClauses, { model });
|
||||
aliasedWhereClauses.forEach(w => buildWhereClause({ qb, ...w }));
|
||||
|
||||
return;
|
||||
buildJoinsFromTree(qb, tree);
|
||||
addFiltersQueriesToJoinTree(tree);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -11,9 +11,9 @@ const {
|
||||
const optionsMap = {
|
||||
publicationState: {
|
||||
queries: {
|
||||
[DP_PUB_STATE_LIVE]: ({ model }) => qb => {
|
||||
[DP_PUB_STATE_LIVE]: ({ model, alias }) => qb => {
|
||||
const { collectionName } = model;
|
||||
qb.whereNotNull(`${collectionName}.${PUBLISHED_AT_ATTRIBUTE}`);
|
||||
qb.whereNotNull(`${alias || collectionName}.${PUBLISHED_AT_ATTRIBUTE}`);
|
||||
},
|
||||
[DP_PUB_STATE_PREVIEW]: () => null,
|
||||
},
|
||||
|
@ -6,7 +6,10 @@ const utils = require('./utils')();
|
||||
const populateQueries = require('./utils/populate-queries');
|
||||
const {
|
||||
hasDeepFilters,
|
||||
contentTypes: { hasDraftAndPublish },
|
||||
contentTypes: {
|
||||
constants: { DP_PUB_STATES },
|
||||
hasDraftAndPublish,
|
||||
},
|
||||
} = require('strapi-utils');
|
||||
|
||||
const combineSearchAndWhere = (search = [], wheres = []) => {
|
||||
@ -139,7 +142,7 @@ const buildDeepQuery = ({ model, filters, search, populate }) => {
|
||||
// Init the query
|
||||
let query = model
|
||||
.aggregate(
|
||||
buildQueryAggregate(model, {
|
||||
buildQueryAggregate(model, filters, {
|
||||
paths: _.merge({}, populatePaths, wherePaths),
|
||||
})
|
||||
)
|
||||
@ -292,7 +295,7 @@ const recursiveCastedWherePaths = (whereClauses, { model }) => {
|
||||
* Builds an object based on paths:
|
||||
* [
|
||||
* 'articles',
|
||||
* 'articles.tags.cateogry',
|
||||
* 'articles.tags.category',
|
||||
* 'articles.tags.label',
|
||||
* ] => {
|
||||
* articles: {
|
||||
@ -307,14 +310,15 @@ const recursiveCastedWherePaths = (whereClauses, { model }) => {
|
||||
const pathsToTree = paths => paths.reduce((acc, path) => _.merge(acc, _.set({}, path, {})), {});
|
||||
|
||||
/**
|
||||
* Builds the aggregations pipeling of the query
|
||||
* Builds the aggregations pipeline of the query
|
||||
* @param {Object} model - Queried model
|
||||
* @param {Object} filters - The query filters
|
||||
* @param {Object} options - Options
|
||||
* @param {Object} options.paths - A tree of paths to aggregate e.g { article : { tags : { label: {}}}}
|
||||
*/
|
||||
const buildQueryAggregate = (model, { paths } = {}) => {
|
||||
const buildQueryAggregate = (model, filters, { paths } = {}) => {
|
||||
return Object.keys(paths).reduce((acc, key) => {
|
||||
return acc.concat(buildLookup({ model, key, paths: paths[key] }));
|
||||
return acc.concat(buildLookup({ model, key, paths: paths[key], filters }));
|
||||
}, []);
|
||||
};
|
||||
|
||||
@ -325,7 +329,7 @@ const buildQueryAggregate = (model, { paths } = {}) => {
|
||||
* @param {string} options.key - The attribute name to lookup on the model
|
||||
* @param {Object} options.paths - A tree of paths to aggregate inside the current lookup e.g { { tags : { label: {}}}
|
||||
*/
|
||||
const buildLookup = ({ model, key, paths }) => {
|
||||
const buildLookup = ({ model, key, paths, filters }) => {
|
||||
const assoc = model.associations.find(a => a.alias === key);
|
||||
const assocModel = strapi.db.getModelByAssoc(assoc);
|
||||
|
||||
@ -341,8 +345,8 @@ const buildLookup = ({ model, key, paths }) => {
|
||||
localAlias: `$${assoc.alias}`,
|
||||
},
|
||||
pipeline: []
|
||||
.concat(buildLookupMatch({ assoc }))
|
||||
.concat(buildQueryAggregate(assocModel, { paths })),
|
||||
.concat(buildLookupMatch({ assoc, assocModel, filters }))
|
||||
.concat(buildQueryAggregate(assocModel, filters, { paths })),
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -351,17 +355,29 @@ const buildLookup = ({ model, key, paths }) => {
|
||||
/**
|
||||
* Build a lookup match expression (equivalent to a SQL join condition)
|
||||
* @param {Object} options - Options
|
||||
* @param {Object} options.assoc - The association on which is based the ematching xpression
|
||||
* @param {Object} options.assoc - The association on which is based the matching expression
|
||||
*/
|
||||
const buildLookupMatch = ({ assoc }) => {
|
||||
const buildLookupMatch = ({ assoc, assocModel, filters = {} }) => {
|
||||
const defaultMatches = [];
|
||||
|
||||
if (hasDraftAndPublish(assocModel) && DP_PUB_STATES.includes(filters.publicationState)) {
|
||||
const dpQuery = populateQueries.publicationState[filters.publicationState];
|
||||
|
||||
if (_.isObject(dpQuery)) {
|
||||
defaultMatches.push(dpQuery);
|
||||
}
|
||||
}
|
||||
|
||||
switch (assoc.nature) {
|
||||
case 'oneToOne': {
|
||||
return [
|
||||
{
|
||||
$match: {
|
||||
$expr: {
|
||||
$eq: [`$${assoc.via}`, '$$localId'],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$eq: [`$${assoc.via}`, '$$localId'],
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -369,9 +385,11 @@ const buildLookupMatch = ({ assoc }) => {
|
||||
case 'oneToMany': {
|
||||
return {
|
||||
$match: {
|
||||
$expr: {
|
||||
$eq: [`$${assoc.via}`, '$$localId'],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$eq: [`$${assoc.via}`, '$$localId'],
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -379,18 +397,22 @@ const buildLookupMatch = ({ assoc }) => {
|
||||
case 'manyToOne': {
|
||||
return {
|
||||
$match: {
|
||||
$expr: {
|
||||
$eq: ['$$localAlias', '$_id'],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$eq: ['$$localAlias', '$_id'],
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
case 'manyWay': {
|
||||
return {
|
||||
$match: {
|
||||
$expr: {
|
||||
$in: ['$_id', '$$localAlias'],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$in: ['$_id', '$$localAlias'],
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -398,18 +420,22 @@ const buildLookupMatch = ({ assoc }) => {
|
||||
if (assoc.dominant === true) {
|
||||
return {
|
||||
$match: {
|
||||
$expr: {
|
||||
$in: ['$_id', '$$localAlias'],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$in: ['$_id', '$$localAlias'],
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
$match: {
|
||||
$expr: {
|
||||
$in: ['$$localId', `$${assoc.via}`],
|
||||
},
|
||||
$and: defaultMatches.concat({
|
||||
$expr: {
|
||||
$in: ['$$localId', `$${assoc.via}`],
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -422,10 +448,10 @@ const buildLookupMatch = ({ assoc }) => {
|
||||
{
|
||||
$match: {
|
||||
$expr: {
|
||||
$and: [
|
||||
$and: defaultMatches.concat(
|
||||
{ $eq: [`$${assoc.via}.ref`, '$$localId'] },
|
||||
{ $eq: [`$${assoc.via}.${assoc.filter}`, assoc.alias] },
|
||||
],
|
||||
{ $eq: [`$${assoc.via}.${assoc.filter}`, assoc.alias] }
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user