feathers-solr
Version:
A Feathers service adapter for Solr
141 lines • 6.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SolrAdapter = void 0;
const errors_1 = require("@feathersjs/errors");
const commons_1 = require("@feathersjs/commons");
const httpClient_1 = require("./httpClient");
const addIds_1 = require("./utils/addIds");
const filterResolver_1 = require("./utils/filterResolver");
const convertOperators_1 = require("./utils/convertOperators");
const adapter_commons_1 = require("@feathersjs/adapter-commons");
class SolrAdapter extends adapter_commons_1.AdapterBase {
constructor(options) {
const { host, core, requestOptions, ...opts } = options;
super(commons_1._.extend({
id: 'id',
commit: {
softCommit: true,
commitWithin: 10000,
overwrite: true
},
queryHandler: '/query',
updateHandler: '/update/json',
defaultSearch: {},
defaultParams: { echoParams: 'none' },
createUUID: true,
escapeFn: (key, value) => ({ key, value }),
logger: (msg) => msg
}, opts));
this.queryHandler = `/${core}${this.options.queryHandler}`;
this.updateHandler = `/${core}${this.options.updateHandler}`;
this.client = (0, httpClient_1.httpClient)(host, requestOptions, this.options.logger);
}
filterQuery(id, params) {
const { paginate } = this.getOptions(params);
const { $search, $params, $select, $filter, $facet, ...adapterQuery } = params.query || {};
const { $skip, $sort, $limit, ...filter } = adapterQuery;
return {
query: {
query: filterResolver_1.filterResolver.$search($search),
fields: filterResolver_1.filterResolver.$select($select),
limit: filterResolver_1.filterResolver.$limit($limit, paginate),
offset: filterResolver_1.filterResolver.$skip($skip),
filter: [
...(id ? (0, convertOperators_1.convertOperators)({ [this.options.id]: id }, this.options.escapeFn) : []),
...(!commons_1._.isEmpty(filter) ? (0, convertOperators_1.convertOperators)(filter, this.options.escapeFn) : []),
...($filter ? $filter : [])
],
...($sort && { sort: filterResolver_1.filterResolver.$sort($sort) }),
...($facet && { facet: $facet }),
...($params && { params: $params })
},
paginate
};
}
async _getOrFind(id, params) {
if (id !== null)
return this._get(id, params);
return this._find(Object.assign(params, { paginate: false }));
}
async _get(id, params = {}) {
const { query } = this.filterQuery(id, params);
const { response } = await this.client.post(this.queryHandler, { data: query });
if (response.numFound === 0)
throw new errors_1.NotFound(`No record found for id '${id}'`);
return response.docs[0];
}
async _find(params = {}) {
const { query, paginate } = this.filterQuery(null, params);
const { responseHeader, response, grouped, ...additionalResponse } = await this.client.post(this.queryHandler, { data: query });
const groupKey = grouped ? Object.keys(grouped)[0] : undefined;
const data = response ? response.docs : grouped[groupKey].groups || grouped[groupKey].doclist.docs;
if (!paginate)
return data;
return {
QTime: responseHeader.QTime || 0,
total: response ? response.numFound : grouped[groupKey].matches,
limit: query.limit,
skip: query.offset,
data,
...additionalResponse
};
}
async _create(data, params = {}) {
if (commons_1._.isEmpty(data))
throw new errors_1.MethodNotAllowed('Data is empty');
const sel = (0, adapter_commons_1.select)(params, this.id);
let dataToCreate = Array.isArray(data) ? [...data] : [{ ...data }];
if (this.options.createUUID) {
dataToCreate = (0, addIds_1.addIds)(dataToCreate, this.options.id);
}
await this.client.post(this.updateHandler, { data: dataToCreate, params: this.options.commit });
return sel(Array.isArray(data) ? dataToCreate : dataToCreate[0]);
}
async _patch(id, _data, params = {}) {
if (id === null && !this.allowsMulti('patch', params)) {
throw new errors_1.MethodNotAllowed('Can not patch multiple entries');
}
const sel = (0, adapter_commons_1.select)(params, this.id);
const response = await this._getOrFind(id, params);
const dataToPatch = Array.isArray(response) ? response : [response];
const patchData = dataToPatch.map((current) => ({
[this.id]: current[this.id], ...Object.fromEntries(Object.entries(_data)
.filter(([field]) => field !== this.id)
.map(([field, value]) => ([field, commons_1._.isObject(value) ? value : value === undefined ? { set: null } : { set: value }])))
}));
await this.client.post(this.updateHandler, { data: patchData, params: this.options.commit });
const ids = dataToPatch.map((d) => d[this.id]);
const result = await this._find({ ...params, query: { id: { $in: ids } } });
return sel(ids.length === 1 && Array.isArray(result) && result.length > 0 ? result[0] : result);
}
async _update(id, data, params = {}) {
if (id === null || Array.isArray(data)) {
throw new errors_1.BadRequest('You can not replace multiple instances. Did you mean \'patch\'?');
}
const sel = (0, adapter_commons_1.select)(params, this.id);
await this._getOrFind(id, params);
await this.client.post(this.updateHandler, {
data: [{ ...data, id }],
params: this.options.commit
});
return this._getOrFind(id, params)
.then(res => sel(commons_1._.omit(res, 'score', '_version_')));
}
async _remove(id, params = {}) {
if (id === null && !this.allowsMulti('remove', params)) {
throw new errors_1.MethodNotAllowed('Can not remove multiple entries');
}
const sel = (0, adapter_commons_1.select)(params, this.id);
const dataToDelete = await this._getOrFind(id, params);
const { query } = this.filterQuery(id, params);
const queryToDelete = id ?
{ delete: id } :
query.filter.length > 0 ?
{ delete: { query: query.filter.join(' AND ') } } :
{ delete: { query: '*:*' } };
await this.client.post(this.updateHandler, { data: queryToDelete, params: this.options.commit });
return sel(dataToDelete);
}
}
exports.SolrAdapter = SolrAdapter;
//# sourceMappingURL=adapter.js.map