graphql-compose-elasticsearch
Version:
Elastic search via GraphQL
215 lines • 8.18 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toDottedList = void 0;
const graphql_compose_1 = require("graphql-compose");
const ElasticApiParser_1 = __importDefault(require("../ElasticApiParser"));
const SearchBody_1 = require("../elasticDSL/SearchBody");
const SearchOutput_1 = require("../types/SearchOutput");
function createSearchResolver(opts) {
const { fieldMap, sourceTC, schemaComposer } = opts;
if (!fieldMap || !fieldMap._all) {
throw new Error('opts.fieldMap for Resolver search() should be fieldMap of FieldsMapByElasticType type.');
}
if (!(sourceTC instanceof graphql_compose_1.ObjectTypeComposer)) {
throw new Error('opts.sourceTC for Resolver search() should be instance of ObjectTypeComposer.');
}
const parser = new ElasticApiParser_1.default({
elasticClient: opts.elasticClient,
prefix: opts.prefix,
});
const searchITC = (0, SearchBody_1.getSearchBodyITC)(opts).removeField([
'size',
'from',
'_source',
'explain',
'version',
]);
const searchFC = parser.generateFieldConfig('search', {
index: opts.elasticIndex,
type: opts.elasticType,
});
const argsConfigMap = Object.assign(Object.assign({}, searchFC.args), { body: {
type: searchITC,
} });
delete argsConfigMap.index;
delete argsConfigMap.type;
delete argsConfigMap.explain;
delete argsConfigMap.version;
delete argsConfigMap._source;
delete argsConfigMap._sourceExclude;
delete argsConfigMap._sourceInclude;
delete argsConfigMap.trackScores;
delete argsConfigMap.size;
delete argsConfigMap.from;
argsConfigMap.limit = 'Int';
argsConfigMap.skip = 'Int';
argsConfigMap.query = searchITC.getField('query');
argsConfigMap.aggs = searchITC.getField('aggs');
argsConfigMap.sort = searchITC.getField('sort');
argsConfigMap.collapse = searchITC.getField('collapse');
argsConfigMap.highlight = searchITC.getField('highlight');
const topLevelArgs = [
'q',
'query',
'collapse',
'sort',
'limit',
'skip',
'aggs',
'highlight',
'opts',
];
argsConfigMap.opts = schemaComposer
.createInputTC({
name: `${sourceTC.getTypeName()}Opts`,
fields: Object.assign({}, argsConfigMap),
})
.removeField(topLevelArgs);
Object.keys(argsConfigMap).forEach((argKey) => {
if (topLevelArgs.indexOf(argKey) === -1) {
delete argsConfigMap[argKey];
}
});
const type = (0, SearchOutput_1.getSearchOutputTC)(opts);
let hitsType;
try {
hitsType = type.get('hits.hits');
}
catch (e) {
hitsType = 'JSON';
}
type
.addFields({
count: 'Int',
max_score: 'Float',
hits: hitsType ? [hitsType] : 'JSON',
})
.reorderFields(['hits', 'count', 'aggregations', 'max_score', 'took', 'timed_out', '_shards']);
return schemaComposer
.createResolver({
type,
name: 'search',
kind: 'query',
args: argsConfigMap,
resolve: (rp) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
let args = rp.args || {};
const projection = rp.projection || {};
if (!args.body)
args.body = {};
if ({}.hasOwnProperty.call(args, 'limit')) {
args.size = args.limit;
delete args.limit;
}
if ({}.hasOwnProperty.call(args, 'skip')) {
args.from = args.skip;
delete args.skip;
}
const { hits = {} } = projection;
if (hits && typeof hits === 'object') {
if (hits._shard || hits._node || hits._explanation) {
args.body.explain = true;
}
if (hits._version) {
args.body.version = true;
}
if (!hits._source) {
args.body._source = false;
}
else {
args.body._source = toDottedList(hits._source);
}
if (hits._score) {
args.body.track_scores = true;
}
}
if (args.query) {
args.body.query = args.query;
delete args.query;
}
if (args.collapse) {
args.body.collapse = args.collapse;
delete args.collapse;
}
if (args.aggs) {
args.body.aggs = args.aggs;
delete args.aggs;
}
if (args.highlight) {
args.body.highlight = args.highlight;
delete args.highlight;
}
if (args.sort) {
args.body.sort = args.sort;
delete args.sort;
}
if (args.opts) {
args = Object.assign(Object.assign(Object.assign({}, args.opts), args), { body: Object.assign(Object.assign({}, args.opts.body), args.body) });
delete args.opts;
}
if (args.body) {
args.body = (0, SearchBody_1.prepareBodyInResolve)(args.body, fieldMap);
}
const res = yield searchFC.resolve(rp.source, args, rp.context, rp.info);
if (typeof res.aggregations === 'undefined') {
res.aggregations = res.body.aggregations;
}
if (typeof res.took === 'undefined') {
res.took = res.body.took;
}
if (typeof res.timed_out === 'undefined') {
res.timed_out = res.body.timed_out;
}
if (typeof res.hits === 'undefined') {
res.count =
typeof ((_a = res.body.hits.total) === null || _a === void 0 ? void 0 : _a.value) === 'number'
? res.body.hits.total.value
: res.body.hits.total;
res.max_score = res.body.hits.max_score;
res.hits = res.body.hits.hits;
}
else {
res.count =
typeof ((_b = res.hits.total) === null || _b === void 0 ? void 0 : _b.value) === 'number' ? res.hits.total.value : res.hits.total;
res.max_score = res.hits.max_score;
res.hits = res.hits.hits;
}
return res;
}),
})
.reorderArgs(['q', 'query', 'collapse', 'sort', 'limit', 'skip', 'aggs']);
}
exports.default = createSearchResolver;
function toDottedList(projection, prev) {
let result = [];
Object.keys(projection).forEach((k) => {
if ((0, graphql_compose_1.isObject)(projection[k])) {
const tmp = toDottedList(projection[k], prev ? [...prev, k] : [k]);
if (Array.isArray(tmp)) {
result = result.concat(tmp);
return;
}
}
if (prev) {
result.push([...prev, k].join('.'));
}
else {
result.push(k);
}
});
return result.length > 0 ? result : true;
}
exports.toDottedList = toDottedList;
//# sourceMappingURL=search.js.map