feathers-solr-node
Version:
Solr Adapter for Feathersjs. Base on Solr-client, so can also used as a Solr-client
243 lines (213 loc) • 5.68 kB
JavaScript
const _ = require('./util');
const errors = require('@feathersjs/errors');
class QueryParser {
constructor(options) {
this.mapKey = {
$select: 'fields',
$search: 'query',
$limit: 'limit',
$skip: 'offset',
$sort: 'sort',
$facet: 'facet',
$params: 'params'
//$qf: "qf"
//'$or':'filter'
};
this.METHODS = ['$or'];
this.setDefaultQuery(options);
}
setDefaultQuery(options) {
this.defaultQuery = {
query: '*:*', // TODO: score
//filter: [],
// sort: '',
fields: _.get(options, 'query.$select') || '*',
limit:
_.get(options, 'paginate.default') ||
_.get(options, 'paginate.max') ||
10,
offset: 0
};
this.rowsMax = _.get(options, 'paginate.max');
}
getDefaultQuery() {
return this.defaultQuery;
}
parseQuery(query) {
let queryObj = Object.assign({}, this.getDefaultQuery());
queryObj.filter = [];
let keys = Object.keys(query);
for (let item of keys) {
if (this.mapKey[item]) {
let value = this[item](item, query[item]);
queryObj[this.mapKey[item]] = value;
} else {
let $filter = this.filterBuilder(item, query[item]);
if ($filter) {
queryObj.filter.push(...$filter);
} else {
return new errors.BadRequest(`undefined field ${item}`);
}
}
}
return queryObj;
}
filterBuilder(item, param) {
if (item === '$or') {
let value = this[item](item, param,true);
return [value];
}
if (item[0] === '$') {
return false;
}
return this.filter(item, param);
}
filter(field, param) {
let $filter = [];
if (_.isObject(param)) {
Object.keys(param).forEach(f => {
if (f[0] === '$' && typeof this[f] !== 'undefined') {
let condition = this[f](field, param[f]);
$filter.push(condition);
}
else {
$filter.push(...this.filter(f, param[f]));
}
});
} else if (Array.isArray(param)) {
param = '(' + param.join(' OR ') + ')';
$filter.push(field + ':' + param);
} else {
$filter.push(field + ':' + param);
}
return $filter;
}
$search(field, param) {
return param;
}
$limit(field, param) {
return parseInt(param) > this.rowsMax ? this.rowsMax : param;
}
$skip(field, param) {
return param;
}
$sort(field, param) {
let order = [];
Object.keys(param).forEach(name => {
order.push(name + (parseInt(param[name]) === 1 ? ' asc' : ' desc'));
});
return order.join(',');
}
$select(field, param) {
if (Array.isArray(param)) {
param = param.join(',');
}
return param;
}
$in(field, param) {
if (Array.isArray(param)) {
param = param.join('" OR "');
}
return field + ':("' + param + '")';
}
$nin(field, param) {
if (Array.isArray(param)) {
param = param.join('" OR "');
}
return '!' + field + ':("' + param + '")';
}
$between(field, param) {
if (Array.isArray(param)) {
param = param.join('" TO "');
}
return field + ':["' + param + '"]';
}
$lt(field, param) {
return field + ':[* TO ' + param + '}';
}
$lte(field, param) {
return field + ':[* TO ' + param + ']';
}
$gt(field, param) {
return field + ':{' + param + ' TO *]';
}
$gte(field, param) {
return field + ':[' + param + ' TO *]';
}
$ne(field, param) {
if (Array.isArray(param)) {
param = param.join('" OR "');
}
return '!' + field + ':"' + param + '"';
}
$or(field, param, root) {
let operator = 'OR';
var $filter = [];
if (Array.isArray(param)) {
param.forEach(item => {
let fq = this.filter(field, item);
if(fq.length>1){
fq = '(' +fq.join(' AND ') +')';
}
$filter.push(fq);
// var f = Object.keys(item)[0];
// if (f[0] === '$' && typeof this[f] !== 'undefined') {
// let condition = this[f](f, item[f]);
// $filter.push(condition);
// } else {
// $filter.push(...this.filter(f, item[f]));
// }
});
} else {
Object.keys(param).forEach(item => {
if (item[0] === '$' && typeof param[item] !== 'undefined') {
let condition = this[item](item, param[item]);
$filter.push(condition);
} else {
$filter.push(...this.filter(item, param[item]));
}
});
}
if(root && $filter.length || $filter.length==1){
return $filter.join(` ${operator} `);
}
else if ($filter.length > 1) {
return '('+ $filter.join(` ${operator} `) + ')';
}
return [];
}
// $or(field, param) {
// return this['$andor']('or', param);
// }
$and(field, param) {
return this['$andor']('or', param);
}
$qf(field, params) {
return Object.assign({}, this.query.params || {}, {
qf: params
});
}
$facet(field, params) {
return params;
}
$params(field, params) {
//return Object.assign(this.query.params || {}, params);
return params;
}
parseDelete(id, params) {
if (id === '*' || id === '*:*') {
return { delete: { query: '*:*' } };
} else if (id) {
return { delete: { id: id } };
} else if (_.isObject(params)) {
let query = [];
Object.keys(params).forEach(field => {
let filter = this.filterBuilder(field, params[field]);
query.push(...filter);
});
return { delete: { query: query.join(' AND ') } };
}
return { delete: { query: '*:*' } };
}
}
module.exports = QueryParser;