@collectionspace/cspace-public-browser
Version:
CollectionSpace public browser
230 lines (196 loc) • 4.45 kB
JavaScript
import config from '../config';
import { SEARCH_QUERY_ID, SORT_ID } from '../constants/ids';
export const fulltextParamToQuery = (value) => {
if (!value) {
return undefined;
}
const fulltextSearchFields = config.get('fulltextSearchFields');
return {
bool: {
should: [
{
multi_match: {
query: value,
fields: fulltextSearchFields,
type: 'cross_fields',
operator: 'and',
},
},
{
multi_match: {
query: value,
fields: fulltextSearchFields,
type: 'phrase_prefix',
operator: 'and',
},
},
],
minimum_should_match: '1',
},
};
};
export const termFilterParamToQuery = (field, value) => ({
terms: {
[field]: value.toJS(),
},
});
export const histogramFilterParamToQuery = (field, value, interval) => {
const clauses = value.map((v) => ({
range: {
[field]: {
gte: v,
lt: v + interval,
},
},
})).toJS();
if (clauses.length === 1) {
return clauses[0];
}
return {
bool: {
should: clauses,
},
};
};
export const filterParamToQuery = (id, value) => {
const filterFieldConfig = config.getFilterFieldConfig(id);
if (!filterFieldConfig) {
return undefined;
}
const {
field,
type,
} = filterFieldConfig;
if (type === 'histogram') {
return histogramFilterParamToQuery(field, value, filterFieldConfig.interval);
}
return termFilterParamToQuery(field, value);
};
export const getSearchQuery = (params) => fulltextParamToQuery(params.get(SEARCH_QUERY_ID));
export const getFilterQueries = (params) => params
.delete(SEARCH_QUERY_ID)
.entrySeq()
.map(([id, value]) => filterParamToQuery(id, value))
.toJS();
export const getQuery = (params) => {
const clauses = [
config.get('defaultQuery'),
getSearchQuery(params),
...getFilterQueries(params),
]
.filter((clause) => !!clause);
if (clauses.length > 1) {
return {
bool: {
must: clauses,
},
};
}
if (clauses.length > 0) {
return clauses[0];
}
return {
match_all: {},
};
};
export const getHistogramAgg = (field, interval = 1) => ({
histogram: {
field,
interval,
min_doc_count: 1,
},
});
export const getTermsAgg = (
field,
order = config.get('filterOrder'),
size = config.get('filterSize'),
) => ({
terms: {
field,
order,
size,
},
});
export const getFilterAgg = (filterFieldConfig) => {
const {
field,
order,
size,
type,
} = filterFieldConfig;
if (type === 'histogram') {
return getHistogramAgg(field, filterFieldConfig.interval);
}
return getTermsAgg(field, order, size);
};
let aggs;
export const getAggs = (params) => {
if (!aggs) {
aggs = {};
const filterFieldsConfig = config.get('filters').fields;
Object.entries(filterFieldsConfig).forEach(([id, filterFieldConfig]) => {
const param = params.get(id);
const hasValue = param && param.size > 0;
if (!hasValue) {
aggs[id] = getFilterAgg(filterFieldConfig);
}
});
}
return aggs;
};
export const getSort = (params) => {
const sortOrder = params.get(SORT_ID) || config.get('defaultSortOrder');
const effectiveSortOrder = (sortOrder === 'bestmatch' && params.delete(SORT_ID).isEmpty())
? 'newest'
: sortOrder;
switch (effectiveSortOrder) {
case 'bestmatch':
return [
{
_score: {
order: 'desc',
},
},
{
[config.get('sortField')]: {
order: 'asc',
},
},
];
case 'atoz':
return {
[config.get('sortField')]: {
order: 'asc',
},
};
case 'ztoa':
return {
[config.get('sortField')]: {
order: 'desc',
},
};
case 'newest':
return {
'collectionspace_core:createdAt': {
order: 'desc',
},
};
case 'oldest':
return {
'collectionspace_core:createdAt': {
order: 'asc',
},
};
default:
return {};
}
};
export const getSearchResultPayload = (params, pageSize, offset) => ({
query: getQuery(params.delete(SORT_ID)),
from: offset,
size: pageSize,
_source: {
includes: config.get('includeFields'),
},
sort: getSort(params),
});