Newer
Older
import { runSelectQuery } from './SparqlApi'
import { has } from 'lodash'
import {
facetValuesQuery,
facetValuesQueryTimespan,
facetValuesRange
facetClass,
facetID,
sortBy,
sortDirection,
const facetConfig = backendSearchConfig[facetClass].facets[facetID]
const { endpoint, defaultConstraint = null, langTag = null } = backendSearchConfig[facetClass]
// choose query template and result mapper:
let q = ''
let mapper = null
switch (facetConfig.type) {
q = facetValuesQuery
mapper = mapFacet
break
q = facetValuesQuery
mapper = mapHierarchicalFacet
break
q = facetValuesQueryTimespan
mapper = mapTimespanFacet
break
q = facetValuesRange
mapper = mapTimespanFacet
break
q = facetValuesQuery
mapper = mapFacet
let selectedBlock = '# no selections'
let selectedNoHitsBlock = '# no filters from other facets'
let currentSelectionsWithoutUnknown = []
if (constraints == null && defaultConstraint == null) {
filterBlock = '# no filters'
} else {
filterBlock = generateConstraintsBlock({
facetClass,
constraints,
defaultConstraint,
constrainSelf // facet does not constrain itself by default
const currentSelections = getUriFilters(constraints, facetID)
// if <http://ldf.fi/MISSING_VALUE> is selected, it needs special care
const { indexOfUnknown, modifiedValues } = handleUnknownValue(currentSelections)
currentSelectionsWithoutUnknown = modifiedValues
const previousSelectionsExist = hasPreviousSelections(constraints, facetID)
const previousSelectionsFromOtherFacetsExist = hasPreviousSelectionsFromOtherFacets(constraints, facetID)
if (indexOfUnknown !== -1) {
unknownSelected = 'true'
}
/* if this facet has previous selections (exluding <http://ldf.fi/MISSING_VALUE>),
they need to be binded as selected */
if (currentSelectionsWithoutUnknown.length > 0 && hasPreviousSelections) {
selectedBlock = generateSelectedBlock({ currentSelectionsWithoutUnknown, literal: facetConfig.literal })
}
/* if there is previous selections in this facet AND in some other facet, we need an
additional block for facet values that return 0 hits */
if (previousSelectionsExist && previousSelectionsFromOtherFacetsExist && currentSelectionsWithoutUnknown.length > 0) {
selectedNoHitsBlock = generateSelectedNoHitsBlock({
backendSearchConfig,
facetClass,
facetID,
constraints,
// no defaultConstraint here
currentSelectionsWithoutUnknown,
literal: facetConfig.literal
q = q.replace('<SELECTED_VALUES>', selectedBlock)
q = q.replace('<SELECTED_VALUES_NO_HITS>', selectedNoHitsBlock)
q = q.replace(/<FACET_VALUE_FILTER>/g, facetConfig.facetValueFilter)
q = q.replace(/<FACET_LABEL_FILTER>/g,
? facetConfig.facetLabelFilter
: ''
q = q.replace('<ORDER_BY>', '# no need for ordering')
q = q.replace(/<PREDICATE>/g, `${facetConfig.predicate}/${facetConfig.parentProperty}*`)
q = q.replace('<PARENTS>', `
OPTIONAL { ?id ${facetConfig.parentProperty} ?parent_ }
BIND(COALESCE(?parent_, '0') as ?parent)
`)
} else {
q = q.replace('<ORDER_BY>', `ORDER BY ${sortDirection}(?${sortBy})`)
q = q.replace(/<PREDICATE>/g, facetConfig.predicate)
q = q.replace('<PARENTS>', ' # no parents')
q = q.replace(/<FILTER>/g, filterBlock)
q = q.replace(/<FACET_CLASS>/g, backendSearchConfig[facetClass].facetClass)
q = q.replace('<UNKNOWN_SELECTED>', unknownSelected)
q = q.replace('<MISSING_PREDICATE>', facetConfig.predicate)
const facetLabelPredicate = facetConfig.facetLabelPredicate
? facetConfig.facetLabelPredicate
q = q.replace('<FACET_LABEL_PREDICATE>', facetLabelPredicate)
if (facetConfig.type === 'timespan') {
q = q.replace('<START_PROPERTY>', facetConfig.startProperty)
q = q.replace('<END_PROPERTY>', facetConfig.endProperty)
if (langTag) {
q = q.replace(/<LANG>/g, langTag)
}
// console.log(endpoint.prefixes + q)
// }
const response = await runSelectQuery({
query: endpoint.prefixes + q,
endpoint: endpoint.url,
useAuth: endpoint.useAuth,
resultMapper: mapper,
resultFormat
if (facetConfig.type === 'hierarchical') {
facetClass: facetClass,
id: facetID,
data: response.data.treeData,
flatData: response.data.flatData,
sparqlQuery: response.sparqlQuery
facetClass: facetClass,
id: facetID,
data: response.data,
sparqlQuery: response.sparqlQuery
const generateSelectedBlock = ({
currentSelectionsWithoutUnknown,
literal
}) => {
const selectedFilter = generateSelectedFilter({
currentSelectionsWithoutUnknown,
return `
OPTIONAL {
${selectedFilter}
BIND(true AS ?selected_)
}
const generateSelectedNoHitsBlock = ({
facetClass,
facetID,
currentSelectionsWithoutUnknown,
literal
const noHitsFilter = generateConstraintsBlock({
filterTarget: 'instance',
facetID: facetID,
const selections = literal ? `'${currentSelectionsWithoutUnknown.join(' ')}'` : `<${currentSelectionsWithoutUnknown.join('> <')}>`
UNION
# facet values that have been selected but return no results
${noHitsFilter}
BIND(true AS ?selected_)
}
const hasPreviousSelections = (constraints, facetID) => {
let hasPreviousSelections = false
if (facet.facetID === facetID && facet.filterType === 'uriFilter') {
hasPreviousSelections = true
}
})
return hasPreviousSelections
}
const hasPreviousSelectionsFromOtherFacets = (constraints, facetID) => {
let hasPreviousSelectionsFromOtherFacets = false
if (facet.facetID !== facetID && facet.filterType === 'uriFilter') {
const unknownAsOnlySelection = facet.values.length === 1 && facet.values[0] === 'http://ldf.fi/MISSING_VALUE'
if (!unknownAsOnlySelection) {
hasPreviousSelectionsFromOtherFacets = true
}
}
})
return hasPreviousSelectionsFromOtherFacets
}
const getUriFilters = (constraints, facetID) => {
let filters = []
if (facet.facetID === facetID && facet.filterType === 'uriFilter') {
filters = facet.values
}
})
return filters
}
export const generateSelectedFilter = ({
currentSelectionsWithoutUnknown,
const selections = literal ? `'${currentSelectionsWithoutUnknown.join(', ')}'` : `<${currentSelectionsWithoutUnknown.join('>, <')}>`
FILTER(?id ${inverse ? 'NOT' : ''} IN ( ${selections} ))