From 604dc9a81bbd0027fd583f46c54d31ef6865c225 Mon Sep 17 00:00:00 2001 From: esikkala <esko.ikkala@aalto.fi> Date: Thu, 27 Jun 2019 12:01:58 +0300 Subject: [PATCH] Use facet priorities, refactor filter constructing --- src/client/reducers/manuscriptsFacets.js | 20 +- src/server/index.js | 26 +-- src/server/sparql/FacetResults.js | 95 ++------ src/server/sparql/FacetValues.js | 117 ++++------ src/server/sparql/Filters.js | 264 ++++++++++++++--------- 5 files changed, 251 insertions(+), 271 deletions(-) diff --git a/src/client/reducers/manuscriptsFacets.js b/src/client/reducers/manuscriptsFacets.js index 16058f3e..964eb520 100644 --- a/src/client/reducers/manuscriptsFacets.js +++ b/src/client/reducers/manuscriptsFacets.js @@ -32,6 +32,7 @@ export const INITIAL_STATE = { containerClass: 'one', filterType: 'textFilter', textFilter: null, + priority: 1 }, productionPlace: { id: 'productionPlace', @@ -51,6 +52,7 @@ export const INITIAL_STATE = { uriFilter: null, spatialFilter: null, type: 'hierarchical', + priority: 4 }, productionTimespan: { id: 'productionTimespan', @@ -70,7 +72,8 @@ export const INITIAL_STATE = { min: null, max: null, timespanFilter: null, - type: 'timespan' + type: 'timespan', + priority: 7 }, author: { id: 'author', @@ -87,7 +90,8 @@ export const INITIAL_STATE = { searchField: true, containerClass: 'ten', filterType: 'uriFilter', - uriFilter: null + uriFilter: null, + priority: 2 }, language: { id: 'owner', @@ -104,7 +108,8 @@ export const INITIAL_STATE = { searchField: true, containerClass: 'ten', filterType: 'uriFilter', - uriFilter: null + uriFilter: null, + priority: 5 }, collection: { id: 'collection', @@ -121,7 +126,8 @@ export const INITIAL_STATE = { searchField: true, containerClass: 'ten', filterType: 'uriFilter', - uriFilter: null + uriFilter: null, + priority: 6 }, owner: { id: 'owner', @@ -138,7 +144,8 @@ export const INITIAL_STATE = { searchField: true, containerClass: 'ten', filterType: 'uriFilter', - uriFilter: null + uriFilter: null, + priority: 3 }, source: { id: 'source', @@ -155,7 +162,8 @@ export const INITIAL_STATE = { searchField: false, containerClass: 'three', filterType: 'uriFilter', - uriFilter: null + uriFilter: null, + priority: 8 }, } }; diff --git a/src/server/index.js b/src/server/index.js index 25a5ef43..2d0a4168 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -43,13 +43,9 @@ app.get(`${apiPath}/:resultClass/paginated`, async (req, res, next) => { resultClass: req.params.resultClass, page: parseInt(req.query.page) || null, pagesize: parseInt(req.query.pagesize) || null, - uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters), - spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters), - textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters), - timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters), sortBy: req.query.sortBy || null, sortDirection: req.query.sortDirection || null, - constraints: req.query.constraints + constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), }); res.json(data); } catch(error) { @@ -62,10 +58,7 @@ app.get(`${apiPath}/:resultClass/all`, async (req, res, next) => { const data = await getAllResults({ resultClass: req.params.resultClass, facetClass: req.query.facetClass || null, - uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters), - spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters), - textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters), - timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters), + constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), variant: req.query.variant || null, }); res.json({ @@ -80,10 +73,7 @@ app.get(`${apiPath}/:resultClass/count`, async (req, res, next) => { try { const count = await getResultCount({ resultClass: req.params.resultClass, - uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters), - spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters), - textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters), - timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters), + constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), }); res.json({ count }); } catch(error) { @@ -96,10 +86,7 @@ app.get(`${apiPath}/:resultClass/instance/:uri`, async (req, res, next) => { const data = await getByURI({ resultClass: req.params.resultClass, facetClass: req.query.facetClass || null, - uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters), - spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters), - textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters), - timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters), + constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), variant: req.query.variant || null, uri: req.params.uri }); @@ -117,10 +104,7 @@ app.get(`${apiPath}/:facetClass/facet/:id`, async (req, res, next) => { facetID: req.params.id, sortBy: req.query.sortBy || null, sortDirection: req.query.sortDirection || null, - uriFilters: req.query.uriFilters == null ? null : JSON.parse(req.query.uriFilters), - spatialFilters: req.query.spatialFilters == null ? null : JSON.parse(req.query.spatialFilters), - textFilters: req.query.textFilters == null ? null : JSON.parse(req.query.textFilters), - timespanFilters: req.query.timespanFilters == null ? null : JSON.parse(req.query.timespanFilters), + constraints: req.query.constraints == null ? null : JSON.parse(req.query.constraints), }); res.json(data); } catch(error) { diff --git a/src/server/sparql/FacetResults.js b/src/server/sparql/FacetResults.js index 68815fb9..65b427d4 100644 --- a/src/server/sparql/FacetResults.js +++ b/src/server/sparql/FacetResults.js @@ -15,18 +15,14 @@ import { facetConfigs } from './FacetConfigs'; import { mapCount } from './Mappers'; import { makeObjectList } from './SparqlObjectMapper'; import { - generateFilter, - hasFilters + generateConstraintsBlock, } from './Filters'; export const getPaginatedResults = async ({ resultClass, page, pagesize, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, sortBy, sortDirection }) => { @@ -34,10 +30,7 @@ export const getPaginatedResults = async ({ resultClass, page, pagesize, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, sortBy, sortDirection }); @@ -51,10 +44,7 @@ export const getPaginatedResults = async ({ export const getAllResults = ({ // resultClass, // TODO: handle other classes than manuscripts facetClass, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, variant }) => { let q = ''; @@ -77,21 +67,12 @@ export const getAllResults = ({ filterTarget = 'manuscript__id'; break; } - const hasActiveFilters = hasFilters({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, - }); - if (!hasActiveFilters) { + if (constraints == null) { q = q.replace('<FILTER>', '# no filters'); } else { - q = q.replace('<FILTER>', generateFilter({ + q = q.replace('<FILTER>', generateConstraintsBlock({ facetClass: facetClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: filterTarget, facetID: null })); @@ -104,29 +85,17 @@ export const getAllResults = ({ export const getResultCount = ({ resultClass, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints }) => { let q = countQuery; q = q.replace('<FACET_CLASS>', facetConfigs[resultClass].facetClass); - const hasActiveFilters = hasFilters({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, - }); - if (!hasActiveFilters) { + if (constraints == null) { q = q.replace('<FILTER>', '# no filters'); } else { - q = q.replace('<FILTER>', generateFilter({ + q = q.replace('<FILTER>', generateConstraintsBlock({ resultClass: resultClass, facetClass: resultClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: 'id', facetID: null })); @@ -138,31 +107,19 @@ const getPaginatedData = ({ resultClass, page, pagesize, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, sortBy, sortDirection }) => { let q = facetResultSetQuery; const facetConfig = facetConfigs[resultClass]; - const hasActiveFilters = hasFilters({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, - }); - if (!hasActiveFilters) { + if (constraints == null) { q = q.replace('<FILTER>', '# no filters'); } else { - q = q.replace('<FILTER>', generateFilter({ + q = q.replace('<FILTER>', generateConstraintsBlock({ resultClass: resultClass, facetClass: resultClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: 'id', facetID: null})); } @@ -206,17 +163,14 @@ const getPaginatedData = ({ resultSetProperties = ''; } q = q.replace('<RESULT_SET_PROPERTIES>', resultSetProperties); - console.log(prefixes + q) + // console.log(prefixes + q) return runSelectQuery(prefixes + q, endpoint, makeObjectList); }; export const getByURI = ({ resultClass, facetClass, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, //variant, uri }) => { @@ -226,22 +180,13 @@ export const getByURI = ({ q = placeQuery; break; } - const hasActiveFilters = hasFilters({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, - }); - if (!hasActiveFilters) { + if (constraints == null) { q = q.replace('<FILTER>', '# no filters'); } else { - q = q.replace('<FILTER>', generateFilter({ + q = q.replace('<FILTER>', generateConstraintsBlock({ resultClass: resultClass, facetClass: facetClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: 'manuscript__id', facetID: null})); } diff --git a/src/server/sparql/FacetValues.js b/src/server/sparql/FacetValues.js index ec2c81db..10f065ef 100644 --- a/src/server/sparql/FacetValues.js +++ b/src/server/sparql/FacetValues.js @@ -1,4 +1,3 @@ -import { has } from 'lodash'; import { runSelectQuery } from './SparqlApi'; import { endpoint, @@ -8,8 +7,10 @@ import { import { prefixes } from './SparqlQueriesPrefixes'; import { facetConfigs } from './FacetConfigs'; import { - hasFilters, - generateFilter, + hasPreviousSelections, + hasPreviousSelectionsFromOtherFacets, + getUriFilters, + generateConstraintsBlock, generateSelectedFilter } from './Filters'; import { @@ -23,10 +24,7 @@ export const getFacet = ({ facetID, sortBy, sortDirection, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, }) => { const facetConfig = facetConfigs[facetClass][facetID]; // choose query template and result mapper: @@ -53,42 +51,29 @@ export const getFacet = ({ let selectedNoHitsBlock = '# no filters from other facets'; let filterBlock = '# no filters'; let parentBlock = '# no parents'; - const hasActiveFilters = hasFilters({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, - }); - if (hasActiveFilters) { - filterBlock = generateFilter({ + if (constraints !== null) { + filterBlock = generateConstraintsBlock({ facetClass: facetClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: 'instance', facetID: facetID, inverse: false, }); - } - // if this facet has previous selections, include them in the query - if (uriFilters !== null && has(uriFilters, facetID)) { - selectedBlock = generateSelectedBlock({ - facetID, - uriFilters - }); - /* - if there are also filters from other facets, we need this - additional block for facet values that return 0 hits - */ - if (Object.keys(uriFilters).length > 1) { - selectedNoHitsBlock = generateSelectedNoHitsBlock({ - facetClass, + // if this facet has previous selections, include them in the query + if (hasPreviousSelections(constraints, facetID)) { + selectedBlock = generateSelectedBlock({ facetID, - uriFilters, - spatialFilters, - textFilters + constraints }); + /* if there are also filters from other facets, we need this + additional block for facet values that return 0 hits */ + if (hasPreviousSelectionsFromOtherFacets(constraints, facetID)) { + selectedNoHitsBlock = generateSelectedNoHitsBlock({ + facetClass, + facetID, + constraints + }); + } } } if (facetConfig.type === 'hierarchical') { @@ -96,10 +81,7 @@ export const getFacet = ({ parentBlock = generateParentBlock({ facetClass, facetID, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, parentPredicate }); } @@ -127,10 +109,11 @@ export const getFacet = ({ const generateSelectedBlock = ({ facetID, - uriFilters, + constraints, }) => { const selectedFilter = generateSelectedFilter({ - selectedValues: uriFilters[facetID], + facetID, + constraints, inverse: false }); return ` @@ -144,17 +127,11 @@ const generateSelectedBlock = ({ const generateSelectedNoHitsBlock = ({ facetClass, facetID, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints }) => { - const noHitsFilter = generateFilter({ + const noHitsFilter = generateConstraintsBlock({ facetClass: facetClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, + constraints: constraints, filterTarget: 'instance', facetID: facetID, inverse: true, @@ -163,7 +140,7 @@ const generateSelectedNoHitsBlock = ({ UNION { # facet values that have been selected but return no results - VALUES ?id { <${uriFilters[facetID].join('> <')}> } + VALUES ?id { <${getUriFilters(constraints, facetID).join('> <')}> } ${noHitsFilter} BIND(true AS ?selected_) } @@ -173,28 +150,26 @@ const generateSelectedNoHitsBlock = ({ const generateParentBlock = ({ facetClass, facetID, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, parentPredicate }) => { - const parentFilterStr = generateFilter({ - facetClass: facetClass, - uriFilters: uriFilters, - spatialFilters: spatialFilters, - textFilters: textFilters, - timespanFilters: timespanFilters, - filterTarget: 'instance2', - facetID: facetID, - inverse: false - }); - let ignoreSelectedValues = ''; - if (uriFilters !== null && has(uriFilters, facetID)) { - ignoreSelectedValues = generateSelectedFilter({ - selectedValues:uriFilters[facetID], - inverse: true + let parentFilterStr = '# no filters'; + let ignoreSelectedValues = '# no selected values'; + if (constraints !== null) { + parentFilterStr = generateConstraintsBlock({ + facetClass: facetClass, + constraints: constraints, + filterTarget: 'instance2', + facetID: facetID, + inverse: false }); + if (hasPreviousSelections) { + ignoreSelectedValues = generateSelectedFilter({ + facetID: facetID, + constraints: constraints, + inverse: true + }); + } } return ` UNION diff --git a/src/server/sparql/Filters.js b/src/server/sparql/Filters.js index b6e2a373..cb323cc4 100644 --- a/src/server/sparql/Filters.js +++ b/src/server/sparql/Filters.js @@ -1,120 +1,188 @@ import { facetConfigs } from './FacetConfigs'; -export const hasFilters = ({ - uriFilters, - spatialFilters, - textFilters, - timespanFilters, -}) => { - return uriFilters !== null - || spatialFilters !== null - || textFilters !== null - || timespanFilters !== null; +export const hasPreviousSelections = (constraints, facetID) => { + let hasPreviousSelections = false; + for (const [key, value] of Object.entries(constraints)) { + if (key === facetID && value.filterType === 'uriFilter') { + hasPreviousSelections = true; + } + } + return hasPreviousSelections; +}; + +export const hasPreviousSelectionsFromOtherFacets = (constraints, facetID) => { + for (const [key, value] of Object.entries(constraints)) { + if (key !== facetID && value.filterType === 'uriFilter') { + return true; + } + } + return false; +}; + +export const getUriFilters = (constraints, facetID) => { + for (const [key, value] of Object.entries(constraints)) { + if (key === facetID && value.filterType === 'uriFilter') { + return value.values; + } + } + return []; }; -export const generateFilter = ({ +export const generateConstraintsBlock = ({ facetClass, - uriFilters, - spatialFilters, - textFilters, - timespanFilters, + constraints, filterTarget, facetID, inverse, }) => { + delete constraints[facetID]; // use only constraints from other facets let filterStr = ''; - let facetProperty = facetID !== null ? facetID : ''; - if (textFilters !== null) { - for (let property in textFilters) { - if (property !== facetProperty) { - const queryString = textFilters[property]; - filterStr += ` - ?${filterTarget} text:query (${facetConfigs[facetClass][property].textQueryProperty} '${queryString}') . - `; - } - } - } - if (spatialFilters !== null) { - for (let property in spatialFilters) { - if (property !== facetProperty) { - const { latMin, longMin, latMax, longMax } = spatialFilters[property]; - filterStr += ` - ?${property}Filter spatial:withinBox (${latMin} ${longMin} ${latMax} ${longMax} 1000000) . - ?${filterTarget} ${facetConfigs[facetClass][property].predicate} ?${property}Filter . - `; - } - } + let constraintsArr = []; + for (const [key, value] of Object.entries(constraints)) { + constraintsArr.push({ + id: key, + filterType: value.filterType, + priority: value.priority, + values: value.values, + }); } - if (timespanFilters !== null) { - for (let property in timespanFilters) { - if (property !== facetProperty) { - const facetConfig = facetConfigs[facetClass][property]; - const { start, end } = timespanFilters[property]; - const selectionStart = start; - const selectionEnd = end; - // filterStr += ` - // ?${filterTarget} ${facetConfig.predicate} ?timespan . - // ?timespan ${facetConfig.startProperty} ?start . - // ?timespan ${facetConfig.endProperty} ?end . - // # both start and end is in selected range - // FILTER(?start >= "${start}"^^xsd:date) - // FILTER(?end <= "${end}"^^xsd:date) - // `; - filterStr += ` - ?${filterTarget} ${facetConfig.predicate} ?timespan . - ?timespan ${facetConfig.startProperty} ?timespanStart . - ?timespan ${facetConfig.endProperty} ?timespanEnd . - # either start or end is in selected range - FILTER( - ?timespanStart >= "${selectionStart}"^^xsd:date && ?timespanStart <= "${selectionEnd}"^^xsd:date - || - ?timespanEnd >= "${selectionStart}"^^xsd:date && ?timespanEnd <= "${selectionEnd}"^^xsd:date - ) - `; - } + constraintsArr.sort((a, b) => a.priority - b.priority); + constraintsArr.map(c => { + switch (c.filterType) { + case 'textFilter': + filterStr += generateTextFilter({ + facetClass: facetClass, + facetID: c.id, + filterTarget: filterTarget, + queryString: c.values + }); + break; + case 'uriFilter': + filterStr += generateUriFilter({ + facetClass: facetClass, + facetID: c.id, + filterTarget: filterTarget, + values: c.values, + inverse: inverse + }); + break; + case 'spatialFilter': + filterStr += generateSpatialFilter({ + facetClass: facetClass, + facetID: c.id, + filterTarget: filterTarget, + values: c.values, + }); + break; + case 'timespanFilter': + filterStr += generateTimespanFilter({ + facetClass: facetClass, + facetID: c.id, + filterTarget: filterTarget, + values: c.values, + }); + break; } + }); + return filterStr; +}; + +const generateTextFilter = ({ + facetClass, + facetID, + filterTarget, + queryString +}) => { + return `?${filterTarget} text:query (${facetConfigs[facetClass][facetID].textQueryProperty} '${queryString}') . `; +}; + +const generateSpatialFilter = ({ + facetClass, + facetID, + filterTarget, + values +}) => { + const { latMin, longMin, latMax, longMax } = values; + return ` + ?${facetID}Filter spatial:withinBox (${latMin} ${longMin} ${latMax} ${longMax} 1000000) . + ?${filterTarget} ${facetConfigs[facetClass][facetID].predicate} ?${facetID}Filter . + `; +}; + +const generateTimespanFilter = ({ + facetClass, + facetID, + filterTarget, + values +}) => { + const facetConfig = facetConfigs[facetClass][facetID]; + const { start, end } = values; + const selectionStart = start; + const selectionEnd = end; + // return ` + // ?${filterTarget} ${facetConfig.predicate} ?timespan . + // ?timespan ${facetConfig.startProperty} ?start . + // ?timespan ${facetConfig.endProperty} ?end . + // # both start and end is in selected range + // FILTER(?start >= "${start}"^^xsd:date) + // FILTER(?end <= "${end}"^^xsd:date) + // `; + return ` + ?${filterTarget} ${facetConfig.predicate} ?timespan . + ?timespan ${facetConfig.startProperty} ?timespanStart . + ?timespan ${facetConfig.endProperty} ?timespanEnd . + # either start or end is in selected range + FILTER( + ?timespanStart >= "${selectionStart}"^^xsd:date && ?timespanStart <= "${selectionEnd}"^^xsd:date + || + ?timespanEnd >= "${selectionStart}"^^xsd:date && ?timespanEnd <= "${selectionEnd}"^^xsd:date + ) + `; +}; + +const generateUriFilter = ({ + facetClass, + facetID, + filterTarget, + values, + inverse +}) => { + let s = ''; + let addChildren = facetConfigs[facetClass][facetID].type == 'hierarchical'; + if (addChildren) { + s = ` + VALUES ?${facetID}Filter { <${values.join('> <')}> } + ?${facetID}FilterWithChildren gvp:broaderPreferred* ?${facetID}Filter . + `; + } else { + s = ` + VALUES ?${facetID}Filter { <${values.join('> <')}> } + `; } - if (uriFilters !== null) { - for (let property in uriFilters) { - // when filtering facet values, apply filters only from other facets - if (property !== facetProperty) { - let addChildren = facetConfigs[facetClass][property].type == 'hierarchical'; - if (addChildren) { - filterStr += ` - VALUES ?${property}Filter { <${uriFilters[property].join('> <')}> } - ?${property}FilterWithChildren gvp:broaderPreferred* ?${property}Filter . - `; - } else { - filterStr += ` - VALUES ?${property}Filter { <${uriFilters[property].join('> <')}> } - `; - } - if (inverse) { - filterStr += ` - FILTER NOT EXISTS { - ?${filterTarget} ${facetConfigs[facetClass][property].predicate} ?${property}Filter . - ?${filterTarget} ${facetConfigs[facetClass][facetID].predicate} ?id . - } - `; - } else { - const filterValue = addChildren - ? `?${property}FilterWithChildren` - : `?${property}Filter`; - filterStr += ` - ?${filterTarget} ${facetConfigs[facetClass][property].predicate} ${filterValue} . - `; - } - } - } + if (inverse) { + s += ` + FILTER NOT EXISTS { + ?${filterTarget} ${facetConfigs[facetClass][facetID].predicate} ?${facetID}Filter . + ?${filterTarget} ${facetConfigs[facetClass][facetID].predicate} ?id . + } + `; + } else { + const filterValue = addChildren + ? `?${facetID}FilterWithChildren` + : `?${facetID}Filter`; + s += ` + ?${filterTarget} ${facetConfigs[facetClass][facetID].predicate} ${filterValue} . + `; } - return filterStr; + return s; }; export const generateSelectedFilter = ({ - selectedValues, + facetID, + constraints, inverse }) => { return (` - FILTER(?id ${inverse ? 'NOT' : ''} IN ( <${selectedValues.join('>, <')}> )) + FILTER(?id ${inverse ? 'NOT' : ''} IN ( <${getUriFilters(constraints, facetID).join('>, <')}> )) `); }; -- GitLab