Skip to content
Snippets Groups Projects
Commit a0f4ba71 authored by esikkala's avatar esikkala
Browse files

Facets to a separate service

parent ea451a33
No related branches found
No related tags found
No related merge requests found
......@@ -21,25 +21,14 @@ const fetchResultsEpic = (action$, state$) => action$.pipe(
withLatestFrom(state$),
mergeMap(([action, state]) => {
const { resultClass } = action;
const resultState = resultStateToUrl(state[resultClass], state[`${resultClass}Facets`]);
const requestUrl = `${apiUrl + resultClass}?${resultState}`;
const params = stateSliceToUrl(state[resultClass], state[`${resultClass}Facets`]);
const requestUrl = `${apiUrl}${resultClass}/results?${params}`;
return ajax.getJSON(requestUrl).pipe(
map(response => updateResults({ data: response }))
);
})
);
// const getPlaces = action$ => action$.pipe(
// ofType(FETCH_PLACES),
// mergeMap(action => {
// const searchUrl = apiUrl + 'places';
// const requestUrl = `${searchUrl}?variant=${action.variant}`;
// return ajax.getJSON(requestUrl).pipe(
// map(response => updatePlaces({ places: response }))
// );
// })
// );
const fetchByURIEpic = action$ => action$.pipe(
ofType(FETCH_BY_URI),
mergeMap(action => {
......@@ -84,12 +73,12 @@ const fetchFacetEpic = (action$, state$) => action$.pipe(
})
);
export const resultStateToUrl = (data, facets) => {
export const stateSliceToUrl = (stateSlice, facets) => {
let params = {
page: data.page,
pagesize: data.pagesize,
sortBy: data.sortBy,
sortDirection: data.sortDirection
page: stateSlice.page,
pagesize: stateSlice.pagesize,
sortBy: stateSlice.sortBy,
sortDirection: stateSlice.sortDirection
};
let filters = {};
let activeFilters = false;
......
import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import {
getManuscripts,
getPlaces,
getPlace,
getFacet
} from './sparql/Manuscripts';
import { getManuscripts } from './sparql/Manuscripts';
import { getFacet } from './sparql/Facets';
const DEFAULT_PORT = 3001;
const app = express();
const apiPath = '/api';
......@@ -24,13 +20,18 @@ app.use(function(req, res, next) {
// Serve the static files from the React app
app.use(express.static(path.join(__dirname, './../public/')));
app.get(`${apiPath}/manuscripts`, (req, res) => {
app.get(`${apiPath}/:resultClass/results`, (req, res) => {
const page = parseInt(req.query.page) || 0;
const pagesize = parseInt(req.query.pagesize) || 5;
const sortBy = req.query.sortBy;
const sortDirection = req.query.sortDirection;
const filters = req.query.filters == null ? null : JSON.parse(req.query.filters);
return getManuscripts(page, pagesize, filters, sortBy, sortDirection).then(data => {
let getResults = null;
switch (req.params.resultClass) {
case 'manuscripts':
getResults = getManuscripts;
}
return getResults(page, pagesize, filters, sortBy, sortDirection).then(data => {
res.json(data);
})
.catch(err => {
......@@ -39,27 +40,6 @@ app.get(`${apiPath}/manuscripts`, (req, res) => {
});
});
app.get(`${apiPath}/places/:placeId?`, (req, res) => {
if (req.params.placeId) {
return getPlace(req.params.placeId).then(data => {
res.json(data[0]);
})
.catch((err) => {
console.log(err);
return res.sendStatus(500);
});
} else {
const variant = req.query.variant ? req.query.variant : 'productionPlaces';
return getPlaces(variant).then((data) => {
res.json(data);
})
.catch((err) => {
console.log(err);
return res.sendStatus(500);
});
}
});
app.get(`${apiPath}/facet/:id`, (req, res) => {
const filters = req.query.filters == null ? null : JSON.parse(req.query.filters);
return getFacet(req.params.id, req.query.sortBy, req.query.sortDirection, filters).then(data => {
......@@ -71,6 +51,27 @@ app.get(`${apiPath}/facet/:id`, (req, res) => {
});
});
// app.get(`${apiPath}/places/:placeId?`, (req, res) => {
// if (req.params.placeId) {
// return getPlace(req.params.placeId).then(data => {
// res.json(data[0]);
// })
// .catch((err) => {
// console.log(err);
// return res.sendStatus(500);
// });
// } else {
// const variant = req.query.variant ? req.query.variant : 'productionPlaces';
// return getPlaces(variant).then((data) => {
// res.json(data);
// })
// .catch((err) => {
// console.log(err);
// return res.sendStatus(500);
// });
// }
// });
/* Routes are matched to a url in order of their definition
Redirect all the the rest for react-router to handle */
app.get('*', function(request, response) {
......
export const facetConfigs = {
productionPlace: {
id: 'productionPlace',
label: 'Production place',
labelPath: '^crm:P108_has_produced/crm:P7_took_place_at/skos:prefLabel',
predicate: '^crm:P108_has_produced/crm:P7_took_place_at',
parentPredicate: '^crm:P108_has_produced/crm:P7_took_place_at/gvp:broaderPreferred+',
type: 'hierarchical',
},
author: {
id: 'author',
label: 'Author',
labelPath: 'mmm-schema:manuscript_author/skos:prefLabel',
predicate: 'mmm-schema:manuscript_author',
type: 'list'
},
source: {
id: 'source',
label: 'Source',
labelPath: 'dct:source/skos:prefLabel',
predicate: 'dct:source',
type: 'list',
},
language: {
id: 'language',
label: 'Language',
labelPath: 'crm:P128_carries/crm:P72_has_language',
predicate: 'crm:P128_carries/crm:P72_has_language',
type: 'list',
},
productionTimespan: {
id: 'productionTimespan',
label: 'Production Date',
labelPath: '^crm:P108_has_produced/crm:P4_has_time-span/skos:prefLabel',
type: 'list',
},
prefLabel: {
id: 'prefLabel',
label: 'Title',
labelPath: 'skos:prefLabel',
type: 'list',
},
event: {
id: 'event',
label: 'Event',
labelPath: '^mmm-schema:observed_manuscript/mmm-schema:observed_time-span',
type: 'list',
},
};
import { has } from 'lodash';
import SparqlSearchEngine from './SparqlSearchEngine';
import datasetConfig from './Datasets';
import { facetConfigs } from './FacetConfigs';
import {
mapFacet,
mapHierarchicalFacet,
} from './Mappers';
const sparqlSearchEngine = new SparqlSearchEngine();
export const getFacet = (id, sortBy, sortDirection, filters) => {
let { endpoint, facetQuery } = datasetConfig['mmm'];
const facetConfig = facetConfigs[id];
let selectedBlock = '# no selections';
let filterBlock = '# no filters';
let parentBlock = '# no parents';
let mapper = mapFacet;
if (filters !== null) {
filterBlock = generateFacetFilter(id, filters);
if (has(filters, id)) {
selectedBlock = `
OPTIONAL {
FILTER(?id IN ( <${filters[id].join('>, <')}> ))
BIND(true AS ?selected_)
}
`;
}
}
if (facetConfig.type === 'hierarchical') {
mapper = mapHierarchicalFacet;
parentBlock = `
UNION
{
${generateFacetFilterParents(id, filters)}
?instance ${facetConfig.parentPredicate} ?id .
BIND(COALESCE(?selected_, false) as ?selected)
OPTIONAL { ?id skos:prefLabel ?prefLabel_ }
BIND(COALESCE(STR(?prefLabel_), STR(?id)) AS ?prefLabel)
OPTIONAL { ?id dct:source ?source }
OPTIONAL { ?id gvp:broaderPreferred ?parent_ }
BIND(COALESCE(?parent_, '0') as ?parent)
}
`;
}
facetQuery = facetQuery.replace(/<FILTER>/g, filterBlock );
facetQuery = facetQuery.replace(/<PREDICATE>/g, facetConfig.predicate);
facetQuery = facetQuery.replace('<SELECTED_VALUES>', selectedBlock);
facetQuery = facetQuery.replace('<PARENTS>', parentBlock);
facetQuery = facetQuery.replace('<ORDER_BY>', `ORDER BY ${sortDirection}(?${sortBy})` );
// if (id == 'productionPlace') {
// //console.log(filters)
// console.log(facetQuery)
// }
return sparqlSearchEngine.doSearch(facetQuery, endpoint, mapper);
};
const generateFacetFilter = (facetId, filters) => {
let filterStr = '';
for (let property in filters) {
if (property !== facetId) {
filterStr += `
VALUES ?${property}Filter { <${filters[property].join('> <')}> }
?instance ${facetConfigs[property].predicate} ?${property}Filter .
`;
}
}
return filterStr;
};
const generateFacetFilterParents = (facetId, filters) => {
let filterStr = '';
for (let property in filters) {
if (property !== facetId) {
filterStr += `
VALUES ?${property}FilterParents { <${filters[property].join('> <')}> }
?instance ${facetConfigs[property].predicate} ?${property}FilterParents .
`;
}
}
return filterStr;
};
import { has } from 'lodash';
import SparqlSearchEngine from './SparqlSearchEngine';
import datasetConfig from './Datasets';
import {
mapFacet,
mapHierarchicalFacet,
mapCount,
} from './Mappers';
import { mapCount } from './Mappers';
import { makeObjectList } from './SparqlObjectMapper';
import { facetConfigs } from './FacetConfigs';
const sparqlSearchEngine = new SparqlSearchEngine();
const facetConfigs = {
productionPlace: {
id: 'productionPlace',
label: 'Production place',
labelPath: '^crm:P108_has_produced/crm:P7_took_place_at/skos:prefLabel',
predicate: '^crm:P108_has_produced/crm:P7_took_place_at',
parentPredicate: '^crm:P108_has_produced/crm:P7_took_place_at/gvp:broaderPreferred+',
type: 'hierarchical',
},
author: {
id: 'author',
label: 'Author',
labelPath: 'mmm-schema:manuscript_author/skos:prefLabel',
predicate: 'mmm-schema:manuscript_author',
type: 'list'
},
source: {
id: 'source',
label: 'Source',
labelPath: 'dct:source/skos:prefLabel',
predicate: 'dct:source',
type: 'list',
},
language: {
id: 'language',
label: 'Language',
labelPath: 'crm:P128_carries/crm:P72_has_language',
predicate: 'crm:P128_carries/crm:P72_has_language',
type: 'list',
},
productionTimespan: {
id: 'productionTimespan',
label: 'Production Date',
labelPath: '^crm:P108_has_produced/crm:P4_has_time-span/skos:prefLabel',
type: 'list',
},
prefLabel: {
id: 'prefLabel',
label: 'Title',
labelPath: 'skos:prefLabel',
type: 'list',
},
event: {
id: 'event',
label: 'Event',
labelPath: '^mmm-schema:observed_manuscript/mmm-schema:observed_time-span',
type: 'list',
},
};
export const getManuscripts = (page, pagesize, filters, sortBy, sortDirection) => {
return Promise.all([
getManuscriptCount(filters),
......@@ -110,79 +56,6 @@ export const getPlace = id => {
return sparqlSearchEngine.doSearch(placeQuery, endpoint, makeObjectList);
};
export const getFacet = (id, sortBy, sortDirection, filters) => {
let { endpoint, facetQuery } = datasetConfig['mmm'];
const facetConfig = facetConfigs[id];
let selectedBlock = '# no selections';
let filterBlock = '# no filters';
let parentBlock = '# no parents';
let mapper = mapFacet;
if (filters !== null) {
filterBlock = generateFacetFilter(id, filters);
if (has(filters, id)) {
selectedBlock = `
OPTIONAL {
FILTER(?id IN ( <${filters[id].join('>, <')}> ))
BIND(true AS ?selected_)
}
`;
}
}
if (facetConfig.type === 'hierarchical') {
mapper = mapHierarchicalFacet;
parentBlock = `
UNION
{
${generateFacetFilterParents(id, filters)}
?instance ${facetConfig.parentPredicate} ?id .
BIND(COALESCE(?selected_, false) as ?selected)
OPTIONAL { ?id skos:prefLabel ?prefLabel_ }
BIND(COALESCE(STR(?prefLabel_), STR(?id)) AS ?prefLabel)
OPTIONAL { ?id dct:source ?source }
OPTIONAL { ?id gvp:broaderPreferred ?parent_ }
BIND(COALESCE(?parent_, '0') as ?parent)
}
`;
}
facetQuery = facetQuery.replace(/<FILTER>/g, filterBlock );
facetQuery = facetQuery.replace(/<PREDICATE>/g, facetConfig.predicate);
facetQuery = facetQuery.replace('<SELECTED_VALUES>', selectedBlock);
facetQuery = facetQuery.replace('<PARENTS>', parentBlock);
facetQuery = facetQuery.replace('<ORDER_BY>', `ORDER BY ${sortDirection}(?${sortBy})` );
// if (id == 'productionPlace') {
// //console.log(filters)
// console.log(facetQuery)
// }
return sparqlSearchEngine.doSearch(facetQuery, endpoint, mapper);
};
const generateFacetFilter = (facetId, filters) => {
let filterStr = '';
for (let property in filters) {
if (property !== facetId) {
filterStr += `
VALUES ?${property}Filter { <${filters[property].join('> <')}> }
?instance ${facetConfigs[property].predicate} ?${property}Filter .
`;
}
}
return filterStr;
};
const generateFacetFilterParents = (facetId, filters) => {
let filterStr = '';
for (let property in filters) {
if (property !== facetId) {
filterStr += `
VALUES ?${property}FilterParents { <${filters[property].join('> <')}> }
?instance ${facetConfigs[property].predicate} ?${property}FilterParents .
`;
}
}
return filterStr;
};
const generateResultFilter = filters => {
let filterStr = '';
for (let property in filters) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment