Skip to content
Snippets Groups Projects
Commit f1b7faf4 authored by Mike Lynch's avatar Mike Lynch
Browse files

Facetting is working and the links are almost there

parent 8f81fdb2
Branches
No related merge requests found
function tryJSON(value) {
try {
return JSON.parse(value);
} catch(e) {
console.error(e);
return null;
}
}
const FacetController = {
get: function({data:arr, toJSON:toJSON}) {
console.log(`FacetController: ${JSON.stringify(arr)}`);
const facets = [];
arr.map(function(value, index, Arr) {
if(index % 2 == 0) {
// if(toJSON){
// try{
// value = JSON.parse(value)
// }catch(e){console.error(e.message);}}
const facet = {
value: value, count: arr[index + 1]
// transforms the solr facets
//
// facetname1: [ f1, count1, f2, count2, f3, count3 ]
//
// into a data structure that the view can use:
//
// facentname1: [ {
// value: f1
// count: count1,
// search: [value to search on for this facet],
// field: [field to search on for this facet]
// } , .. ]
//
// it tries to parse the JSON and pull out the right values
// to display and search if so configured
process: function({data: data, config: config}) {
const facets = {};
for( let name in data ) {
facets[name] = [];
const cfa = config.filter((c) => c.name === name);
if( cfa.length !== 1 ) {
console.error("No config found for facet " + name);
} else {
const cf = cfa[0];
const parseJson = cf['JSON'];
for( let i = 0; i < data[name].length; i += 2 ) {
if( parseJson ) {
const value = tryJSON(data[name][i]);
facets[name].push({
value: value[cf['display']],
count: data[name][i + 1],
search: value[cf['search']],
field: cf['field']
})
} else {
facets[name].push({
value: data[name][i],
count: data[name][i + 1],
search: data[name][i],
field: cf['field']
});
}
facets.push(facet);
}
});
console.log(`FacetController: facets ${JSON.stringify(facets)}`);
return facets;
},
display: function ({data: data, config: config}) {
const displays = [];
data.forEach(function(d){
const displayFacet = {
count:d.count,
name: config.name,
route: config.route,
searchUrl: d.value[config.searchUrl],
searchText: d.value[config.searchText]
}
displays.push(displayFacet)
});
console.log(`FacetController: displays ${JSON.stringify(displays)}`);
return displays;
}
}
return facets;
}
module.exports = FacetController;
}
module.exports = FacetController;
......@@ -30,7 +30,7 @@ const Router = async function (state) {
const res = await solrService.search({api: state.config.api}, {
start: 0,
page: 1,
searchParam: 'author_id%3A',
searchParam: 'uri_id',
text: state.main.doc.id,
facets: false
});
......@@ -43,24 +43,36 @@ const Router = async function (state) {
app.innerHTML = [Container([Header(state), Menu(state), Search(state), ViewError(state), Footer(state)])].join('');
}
}
// this needs to be able to specify a search param for facets
// and facets should be able to compose
if (verb === '#search/') {
//TODO: make the split better
// ML: I made it a bit worse by adding search params
const splits = match[2].split('/');
console.log("Search splits = " + JSON.stringify(splits));
const start = splits[0] || state.main.start;
const page = splits[1] || '';
let searchText = splits[2] || '';
const {data, status} = await solrService.search({api: state.config.api}, {
var searchParam = state.search.mainSearch;
var searchText = splits[2] || '';
const searchparts = searchText.split('=');
if( searchparts.length === 2 ) {
searchParam = searchparts[0];
searchText = searchparts[1];
}
const res = await solrService.search({api: state.config.api}, {
start: start,
page: page,
searchParam: 'main_search%3A',
searchParam: searchParam,
text: searchText,
facets: state.facets,
facets: state.facets.map((f) => f.name),
facetLimit: state.facetLimit
});
if (status === 200) {
state.main.docs = data.docs;
state.main.numFound = data.numFound;
if (res.status === 200) {
state.main.docs = res.data.docs;
state.main.numFound = res.data.numFound;
state.main.searchText = searchText;
state.facetResult = res.facets;
state.facetData = FacetController.process({config: state.facets, data: state.facetResult['facet_fields']});
app.innerHTML = [Container([Header(state), Menu(state), Search(state), Main(state), Footer(state)])].join('');
const input = document.getElementById('text-to-search');
if (input) {
......@@ -75,9 +87,9 @@ const Router = async function (state) {
const res = await solrService.search({api: state.config.api}, {
start: state.main.start,
page: state.main.page,
searchParam: '*%3A',
searchParam: '*',
text: '*',
facets: state.facets,
facets: state.facets.map((f) => f.name),
facetLimit: state.facetLimit
});
if (res.status === 200) {
......@@ -85,17 +97,7 @@ const Router = async function (state) {
state.main.numFound = res.data.numFound;
state.main.searchText = '';
state.facetResult = res.facets;
console.log(`facet results: ${JSON.stringify(res.facets)}`);
const facetContent = FacetController.get({data: state.facetResult['facet_fields'][state.facets[0]], toJSON: true});
// TODO: Move this to config
const facetData = FacetController.display({data: facetContent, config: {
name: 'Dataset_author_facet',
route: '#view/',
searchUrl: '@id',
searchText: 'name'
}
});
state.facetData = facetData;
state.facetData = FacetController.process({config: state.facets, data: state.facetResult['facet_fields']});
app.innerHTML = [Container([Header(state), Menu(state), Search(state), Main(state), Footer(state)])].join('');
} else {
app.innerHTML = [Container([Header(state), Menu(state), Search(state), ViewError(state), Footer(state)])].join('');
......
......@@ -21,8 +21,8 @@ const SolrService = {
if (text === '' || !text ) {
text = '*';
}
let escText = text.replace(':', "\\:");
let query = `${param}${searchParam}${escText}&start=${start}&page=${page}`;
let escSearch = searchParam + '%3A' + text.replace(':', "\\:");
let query = `${param}${escSearch}&start=${start}&page=${page}`;
if(facets) {
query += `&facet=true%20&facet.field=${[...facets].join('&facet.field=')}&facet.limit=${facetLimit || 5}`;
......
......@@ -3,30 +3,27 @@ const isIterable = require('../isIterable');
const Facets = function (data) {
let html = '';
console.log(`Facets: ${JSON.stringify(data.facetsDisplay)}`);
console.log(`Facets: ${JSON.stringify(data.facetData)}`);
if(isIterable(data.facetsDisplay) ){
if(isIterable(data.facets) ){
html = `<ul class="list-group col-md-2">`;
for(let fd of data.facetsDisplay){
for(let facet of data.facets) {
const values = data.facetData[facet.name].filter((v)=>v['count'] > 0);
html += `<li class="list-group-item">
<div>
<h4>${fd.displayText}</h4>
<h4>${facet.label}</h4>
<hr/>
<ul class="list-group">`;
console.log(`fdname = ${fd.name}, all facets = ${JSON.stringify(data.facetData)}`);
const currentFacet = data.facetData.filter((f)=>{
return f.name === fd.name;
});
console.log(`filtered currentFacet = ${JSON.stringify(currentFacet)}`);
if(isIterable(currentFacet)){
for(let facet of currentFacet){
html += `<li class="row">
<div class="col-sm-4">${facet['count']}</div>
<div class="col-sm-8"><a href="/${facet['route']}${facet['searchUrl']}">${facet['searchText']}</a></div>
if(isIterable(values))
{
for(let f of values ){
html += `<li class="row">
<div class="col-sm-4">${f['count']}</div>
<div class="col-sm-8"><a href="/#search/${facet['field']}=${encodeURIComponent('"' + f['search'] + '"')}">${f['value']}</a></div>
</li>`;
}
}
html += `</ul>
}
}
html += `</ul>
</div>
</li>`
}
......
......@@ -11,7 +11,7 @@ const RegisterEvents = require('./components/RegisterEvents');
//Default state
let state = {
header: {
title: 'Research Data Portal',
title: 'Successful Grants',
URL: '/',
logo: 'images/logo.svg',
help: 'Help',
......@@ -25,7 +25,8 @@ let state = {
search: {
error: 'Search Error',
invalidSearch: 'Invalid Search',
searchText: 'Search'
searchText: 'Search',
mainSearch: 'main_search'
},
main: {
docs: [],
......@@ -43,21 +44,34 @@ let state = {
{display: "SubDoc", field: "contactPoint", fieldName: 'Contact Point', template: '${item.name} ${item.email}'},
]
},
facets: [
'Dataset_author_facet',
'Dataset_keywords_facetmulti',
'Dataset_FOR_facetmulti'
{
name: 'Dataset_author_facet',
label: 'Author',
field: 'author',
JSON: false
},
{
name: 'Dataset_keywords_facetmulti',
label: 'Keywords',
field: 'keywords',
JSON: false
},
{
name: 'Dataset_FOR_facetmulti',
label: 'FORs',
JSON: true,
search: '@id',
display: 'name',
field: 'FOR_id'
}
],
facetsDisplay: [
{name: 'Dataset_author_facet', displayText: 'Author'},
{name: 'Dataset_keywords_facetmulti', displayText: 'Keywords'},
{name: 'Dataset_FOR_facetmulti', displayText: 'FORs'}
],
facetData: [],
facetLimit: 5,
footer:{
text: '2019 University of Technology Sydney'
text: '2020 University of Technology Sydney'
},
config: config
};
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment