From 8ddd1e1941029842a2bc869b38dc64e01c707452 Mon Sep 17 00:00:00 2001 From: leonardosfl Date: Mon, 3 Aug 2020 20:23:33 -0300 Subject: [PATCH 1/2] Allow multiple terms to be used on search --- src/components/dashboard.js | 19 ++++++------- src/utils/search.js | 54 ++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/components/dashboard.js b/src/components/dashboard.js index 48afc7b..bfd3bcf 100644 --- a/src/components/dashboard.js +++ b/src/components/dashboard.js @@ -49,16 +49,17 @@ export default function Dashboard() { location.state && location.state.bookmark ); + const covidTerms = ['COVID-19', 'Coronavirus', 'SARS-CoV-2']; const params = new URLSearchParams(location.search); useEffect(() => { if (location.search === "") { - history.replace({ search: "q=COVID-19" }) + history.replace({ search: createPreprintQs({ text: covidTerms }, location.search) }); } }, [apiQs]); const [preprints, fetchResultsProgress] = usePreprintSearchResults(apiQs); - + const [hoveredSortOption, setHoveredSortOption] = useState(null); /** @@ -189,7 +190,7 @@ export default function Dashboard() { onChange={e => { const search = createPreprintQs( { - text: 'COVID-19', + text: covidTerms, hasOthersRec: e.target.checked || null }, location.search @@ -216,7 +217,7 @@ export default function Dashboard() { onChange={e => { const search = createPreprintQs( { - text: 'COVID-19', + text: covidTerms, hasPeerRec: e.target.checked || null }, location.search @@ -243,7 +244,7 @@ export default function Dashboard() { onChange={e => { const search = createPreprintQs( { - text: 'COVID-19', + text: covidTerms, hasData: e.target.checked || null }, location.search @@ -270,7 +271,7 @@ export default function Dashboard() { onChange={e => { const search = createPreprintQs( { - text: 'COVID-19', + text: covidTerms, hasCode: e.target.checked || null }, location.search @@ -298,7 +299,7 @@ export default function Dashboard() { ) => { const search = createPreprintQs( { - text: 'COVID-19' || 'coronavirus' || 'SARS-CoV2', + text: covidTerms, sort: nextSortOption }, location.search @@ -346,7 +347,7 @@ export default function Dashboard() { onClick={() => { history.push({ pathname: location.pathname, - search: createPreprintQs({ text: params.get('q') }, location.search) + search: createPreprintQs({ text: params.getAll('q') }, location.search) }); }} > @@ -363,7 +364,7 @@ export default function Dashboard() { onClick={() => { history.push({ pathname: location.pathname, - search: createPreprintQs({ text: params.get('q') }, location.search), + search: createPreprintQs({ text: params.getAll('q') }, location.search), state: { bookmark: preprints.bookmark } }); }} diff --git a/src/utils/search.js b/src/utils/search.js index 448d81d..c1e4613 100644 --- a/src/utils/search.js +++ b/src/utils/search.js @@ -23,7 +23,12 @@ export function createPreprintQs( const ui = new URLSearchParams(uiQs); if (text != null && text != '') { - ui.set('q', text); + if (Array.isArray(text)) { + ui.delete('q'); + text.forEach(term => ui.append('q', term)); + } else { + ui.set('q', text); + } } else { ui.delete('q'); } @@ -112,26 +117,10 @@ export function apifyPreprintQs(uiQs = '', bookmark) { const drilldown = []; if (ui.has('q')) { - const q = ui.get('q'); - const terms = q.split(/[+|\s]/).filter(Boolean); - - const ored = [`name:"${escapeLucene(q)}"`]; - - if (terms.length > 1) { - ored.push(`name:"${escapeLucene(q)}"~5`); - } else if (terms.length === 1) { - ored.push(`name:${escapeLucene(terms[0])}*`); - } - - const doiMatched = q.match(doiRegex()); - if (doiMatched) { - ored.push(...doiMatched.map(doi => `doi:"${doi}"`)); - } - - const arXivIds = identifiersArxiv.extract(q); - if (arXivIds && arXivIds.length) { - ored.push(...arXivIds.map(arXivId => `arXivId:"${arXivId}"`)); - } + const searchTerms = ui.getAll('q'); + const ored = searchTerms.length > 1 + ? searchTerms.map(q => buildLuceneQueryForTerm(q)).reduce((prev, curr) => prev.concat(curr)) + : buildLuceneQueryForTerm(searchTerms[0]); anded.push(ored.length == 1 ? ored[0] : `(${ored.join(' OR ')})`); } @@ -398,3 +387,26 @@ export function createBlockedRolesQs({ bookmark }) { function escapeLucene(term) { return term.replace(/([+&|!(){}[\]^"~*?:\\\/-])/g, '\\$1'); } + +function buildLuceneQueryForTerm(q) { + const result = [`name:"${escapeLucene(q)}"`]; + const words = q.split(/[+|\s]/).filter(Boolean); + + if (words.length > 1) { + result.push(`name:"${escapeLucene(q)}"~5`); + } else if (words.length === 1) { + result.push(`name:${escapeLucene(words[0])}*`); + } + + const doiMatched = q.match(doiRegex()); + if (doiMatched) { + result.push(...doiMatched.map(doi => `doi:"${doi}"`)); + } + + const arXivIds = identifiersArxiv.extract(q); + if (arXivIds && arXivIds.length) { + result.push(...arXivIds.map(arXivId => `arXivId:"${arXivId}"`)); + } + + return result; +} \ No newline at end of file From 930e111e88f2d0c3f39bc787ceb5d92cbb476ba1 Mon Sep 17 00:00:00 2001 From: leonardosfl Date: Mon, 3 Aug 2020 20:57:24 -0300 Subject: [PATCH 2/2] Add test --- test/test-search-utils.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test-search-utils.js b/test/test-search-utils.js index ffe0f98..a7097f4 100644 --- a/test/test-search-utils.js +++ b/test/test-search-utils.js @@ -40,6 +40,15 @@ describe('search utils', () => { ); }); + it('should allow multiple terms to be used', () => { + const ui = createPreprintQs({ text: ['text1', 'text2'] }); + + assert.equal(ui, '?q=text1&q=text2'); + + const p = querystring.parse(apifyPreprintQs(ui).substring(1)); + assert.equal(p.q, '(name:"text1" OR name:text1* OR name:"text2" OR name:text2*)' ); + }); + it('should handle DOI and arXivId', () => { const ui = createPreprintQs({ text: `text ${arXivId} ${crossrefDoi} ${openAireDoi}`