@webiny/api-page-builder-so-ddb-es
Version:
The DynamoDB + Elasticsearch storage operations Webiny Page Builder API.
213 lines (209 loc) • 5.91 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createElasticsearchQueryBody = void 0;
var _error = _interopRequireDefault(require("@webiny/error"));
var _apiElasticsearch = require("@webiny/api-elasticsearch");
var _PageElasticsearchFieldPlugin = require("../../plugins/definitions/PageElasticsearchFieldPlugin");
var _PageElasticsearchSortModifierPlugin = require("../../plugins/definitions/PageElasticsearchSortModifierPlugin");
var _PageElasticsearchQueryModifierPlugin = require("../../plugins/definitions/PageElasticsearchQueryModifierPlugin");
var _PageElasticsearchBodyModifierPlugin = require("../../plugins/definitions/PageElasticsearchBodyModifierPlugin");
/**
* Latest and published are specific in Elasticsearch to that extend that they are tagged in the published or latest property.
* We allow either published or either latest.
* Latest is used in the manage API and published in the read API.
*/
const createInitialQueryValue = args => {
const {
where
} = args;
const query = {
must: [],
must_not: [],
should: [],
filter: []
};
/**
* We must transform published and latest where args into something that is understandable by our Elasticsearch
*/
if (where.published === true) {
query.must.push({
term: {
published: true
}
});
} else if (where.latest === true) {
query.must.push({
term: {
latest: true
}
});
}
// we do not allow not published and not latest
else if (where.published === false) {
throw new _error.default(`Cannot call Elasticsearch query with "published" set at false.`, "ELASTICSEARCH_UNSUPPORTED_QUERY", {
where
});
} else if (where.latest === false) {
throw new _error.default(`Cannot call Elasticsearch query with "latest" set at false.`, "ELASTICSEARCH_UNSUPPORTED_QUERY", {
where
});
}
delete where.published;
delete where.latest;
//
return query;
};
const createElasticsearchQuery = params => {
const {
plugins,
where: initialWhere,
fieldPlugins
} = params;
const query = createInitialQueryValue({
where: initialWhere
});
/**
* Be aware that, if having more registered operator plugins of same type, the last one will be used.
*/
const operatorPlugins = (0, _apiElasticsearch.getElasticsearchOperatorPluginsByLocale)(plugins, initialWhere.locale);
const where = {
...initialWhere
};
/**
* Tags are specific so extract them and remove from where.
*/
const {
tags_in: tags,
tags_rule: tagsRule
} = initialWhere;
delete where["tags_in"];
delete where["tags_rule"];
if (tags && Array.isArray(tags) === true && tags.length > 0) {
if (tagsRule === "any") {
query.filter.push({
terms: {
"tags.keyword": tags
}
});
} else {
query.filter.push({
bool: {
must: tags.map(tag => {
return {
term: {
"tags.keyword": tag
}
};
})
}
});
}
}
/**
* Specific search parameter
*/
if (where.search) {
query.must.push({
query_string: {
query: `*${where.search}*`,
allow_leading_wildcard: true,
fields: ["titleLC", "snippet"]
}
});
}
delete where.search;
/**
* !!! IMPORTANT !!! There are few specific cases where we hardcode the query conditions.
*
* When ES index is shared between tenants, we need to filter records by tenant ID.
*/
const sharedIndex = (0, _apiElasticsearch.isSharedElasticsearchIndex)();
if (sharedIndex) {
const tenant = initialWhere.tenant;
query.must.push({
term: {
"tenant.keyword": tenant
}
});
/**
* Remove so it is not applied again later.
* Possibly tenant is not defined, but just in case, remove it.
*/
delete where["tenant"];
}
/**
* We apply other conditions as they are passed via the where value.
*/
(0, _apiElasticsearch.applyWhere)({
query,
where,
fields: fieldPlugins,
operators: operatorPlugins
});
return query;
};
const createElasticsearchQueryBody = params => {
const {
plugins,
where,
limit: initialLimit,
sort: initialSort,
after
} = params;
const fieldPlugins = plugins.byType(_PageElasticsearchFieldPlugin.PageElasticsearchFieldPlugin.type).reduce((acc, plugin) => {
acc[plugin.field] = plugin;
return acc;
}, {});
const limit = (0, _apiElasticsearch.createLimit)(initialLimit, 100);
const query = createElasticsearchQuery({
...params,
fieldPlugins
});
const sort = (0, _apiElasticsearch.createSort)({
sort: initialSort,
fieldPlugins
});
const queryModifiers = plugins.byType(_PageElasticsearchQueryModifierPlugin.PageElasticsearchQueryModifierPlugin.type);
for (const plugin of queryModifiers) {
plugin.modifyQuery({
query,
where,
sort,
limit
});
}
const sortModifiers = plugins.byType(_PageElasticsearchSortModifierPlugin.PageElasticsearchSortModifierPlugin.type);
for (const plugin of sortModifiers) {
plugin.modifySort({
sort,
where
});
}
const body = {
query: {
constant_score: {
filter: {
bool: {
...query
}
}
}
},
size: limit + 1,
search_after: (0, _apiElasticsearch.decodeCursor)(after),
sort
};
const bodyModifiers = plugins.byType(_PageElasticsearchBodyModifierPlugin.PageElasticsearchBodyModifierPlugin.type);
for (const plugin of bodyModifiers) {
plugin.modifyBody({
body,
where
});
}
return body;
};
exports.createElasticsearchQueryBody = createElasticsearchQueryBody;
//# sourceMappingURL=elasticsearchQueryBody.js.map