Skip to content
Snippets Groups Projects
FacetValues.js 3.73 KiB
Newer Older
esikkala's avatar
esikkala committed
import { has } from 'lodash';
import { runSelectQuery } from './SparqlApi';
import { endpoint, facetValuesQuery } from './SparqlQueriesGeneral';
import { prefixes } from './SparqlQueriesPrefixes';
esikkala's avatar
esikkala committed
import { facetConfigs } from './FacetConfigs';
import { generateFilter, generateSelectedFilter } from './Filters';
esikkala's avatar
esikkala committed
import {
  mapFacet,
  mapHierarchicalFacet,
} from './Mappers';

export const getFacet = ({
  facetClass,
  facetID,
  sortBy,
  sortDirection,
  uriFilters,
  spatialFilters,
esikkala's avatar
esikkala committed
  textFilters
  let q = facetValuesQuery;
  const facetConfig = facetConfigs[facetClass][facetID];
esikkala's avatar
esikkala committed
  let selectedBlock = '# no selections';
esikkala's avatar
esikkala committed
  let selectedNoHitsBlock = '# no filters from other facets';
esikkala's avatar
esikkala committed
  let filterBlock = '# no filters';
  let parentBlock = '# no parents';
  let mapper = mapFacet;
esikkala's avatar
esikkala committed
  const hasFilters = uriFilters !== null
    || spatialFilters !== null
    || textFilters !== null;

  if (hasFilters) {
    filterBlock = generateFilter({
      facetClass: facetClass,
      uriFilters: uriFilters,
      spatialFilters: spatialFilters,
esikkala's avatar
esikkala committed
      textFilters: textFilters,
      filterTarget: 'instance',
      facetID: facetID,
      inverse: false,
    });
  }
  if (uriFilters !== null && has(uriFilters, facetID)) {
    const selectedFilter = generateSelectedFilter({
      selectedValues:uriFilters[facetID],
      inverse: false
    });
    selectedBlock = `
              ${selectedFilter}
              BIND(true AS ?selected_)
    const facetIDs = Object.keys(uriFilters);
    // get selected values with no hits, only when there are filters from
    // other facets
    if (facetIDs.length > 1) {
      const noHitsFilter = generateFilter({
        facetClass: facetClass,
        uriFilters: uriFilters,
        spatialFilters: spatialFilters,
esikkala's avatar
esikkala committed
        textFilters: textFilters,
        filterTarget: 'instance',
        facetID: facetID,
        inverse: true,
      });
      selectedNoHitsBlock = `
esikkala's avatar
esikkala committed
    UNION
    {
    # facet values that have been selected but return no results
      VALUES ?id { <${uriFilters[facetID].join('> <')}> }
      ${noHitsFilter}
      BIND(true AS ?selected_)
    }
esikkala's avatar
esikkala committed
  }
  if (facetConfig.type === 'hierarchical') {
    mapper = mapHierarchicalFacet;
    const parentFilterStr = generateFilter({
      facetClass: facetClass,
      uriFilters: uriFilters,
      spatialFilters: spatialFilters,
esikkala's avatar
esikkala committed
      textFilters: textFilters,
      filterTarget: 'instance2',
esikkala's avatar
esikkala committed
      facetID: facetID,
      inverse: false
    });
    let ignoreSelectedValues = '';
    if (uriFilters !== null && has(uriFilters, facetID)) {
      ignoreSelectedValues = generateSelectedFilter({
        selectedValues:uriFilters[facetID],
        inverse: true
      });
esikkala's avatar
esikkala committed
    parentBlock = `
          UNION
          # parents for all facet values
          {
            ${parentFilterStr}
            # these instances should not be counted, so use another variable name
            ?instance2 ${facetConfig.parentPredicate} ?id .
esikkala's avatar
esikkala committed
            VALUES ?facetClass { <FACET_CLASS> }
            ?instance2 a ?facetClass .
            BIND(false AS ?selected_)
            ${ignoreSelectedValues}
          }
  q = q.replace('<SELECTED_VALUES>', selectedBlock);
  q = q.replace('<SELECTED_VALUES_NO_HITS>', selectedNoHitsBlock);
esikkala's avatar
esikkala committed
  q = q.replace('<FACET_VALUE_FILTER>', facetConfig.facetValueFilter);
  q = q.replace('<PARENTS>', parentBlock);
  q = q.replace('<ORDER_BY>', `ORDER BY ${sortDirection}(?${sortBy})` );
esikkala's avatar
esikkala committed
  q = q.replace(/<FACET_CLASS>/g, facetConfigs[facetClass].facetClass);
  q = q.replace(/<FILTER>/g, filterBlock );
  q = q.replace(/<PREDICATE>/g, facetConfig.predicate);
  // if (facetID == 'productionPlace') {
esikkala's avatar
esikkala committed
  //   console.log(prefixes + q)
  // }
  return runSelectQuery(prefixes + q, endpoint, mapper);