UNPKG

@webiny/api-page-builder-so-ddb-es

Version:

The DynamoDB + Elasticsearch storage operations Webiny Page Builder API.

213 lines (209 loc) 5.91 kB
"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