Skip to content

Commit

Permalink
new option on AGGREGATION_FILTER to show/hide empty buckets
Browse files Browse the repository at this point in the history
  • Loading branch information
fergiemcdowall committed Oct 25, 2023
1 parent 93041fe commit ab7ded3
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 21 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,10 @@ const ii = await InvertedIndex({ name: 'myIndex' })

<a name="AGGREGATION_FILTER"></a>

### `AGGREGATION_FILTER(aggregation, query).then(result)`
### `AGGREGATION_FILTER(aggregation, query, trimEmpty).then(result)`

The aggregation (either FACETS or BUCKETS) is filtered by the query
The aggregation (either FACETS or BUCKETS) is filtered by the
query. Use boolean `trimEmpty` to show or hide empty buckets

```javascript
Promise.all([
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fergies-inverted-index",
"version": "13.0.0-rc.4",
"version": "13.0.0-rc.5",
"description": "An inverted index that allows javascript objects to be easily serialised and retrieved using promises and map-reduce",
"browser": "src/entrypoints/browser.js",
"main": "src/entrypoints/node.js",
Expand Down
23 changes: 17 additions & 6 deletions src/read.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,24 @@ export default function (ops, tokenParser) {

// Given the results of an aggregation and the results of a query,
// return the filtered aggregation
const AGGREGATION_FILTER = (aggregation, filterSet) => {
if (!filterSet || filterSet.length === 0) return aggregation
const AGGREGATION_FILTER = (aggregation, filterSet, trimEmpty = true) => {
// console.log(aggregation)
// console.log(JSON.stringify(filterSet, null, 2))

if (!filterSet) return aggregation // no filter provided- return everything
if (filterSet.length === 0) return [] // search returned no results

filterSet = new Set(filterSet.map(item => item._id))
return aggregation.map(bucket =>
Object.assign(bucket, {
_id: [...new Set([...bucket._id].filter(x => filterSet.has(x)))]
})

return (
aggregation
.map(bucket =>
Object.assign(bucket, {
_id: [...new Set([...bucket._id].filter(x => filterSet.has(x)))]
})
)
// remove empty buckets
.filter(facet => (trimEmpty ? facet._id.length : true))
)
}

Expand Down
94 changes: 82 additions & 12 deletions test/src/AGGREGATION_FILTER-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ test('can add some data', t => {
global[indexName].PUT(data).then(t.pass)
})

test('use AGGREGATION_FILTER with FACETS, 0-hit query', t => {
t.plan(1)
const { FACETS, AGGREGATION_FILTER, AND } = global[indexName]
Promise.all([
FACETS({
FIELD: ['year']
}),
AND([37512, 'colour:White'])
]).then(([facetResult, queryResult]) => {
t.deepEqual(AGGREGATION_FILTER(facetResult, queryResult), [
{ FIELD: 'year', VALUE: 2004, _id: [9] }
])
})
})

test('use AGGREGATION_FILTER with FACETS', t => {
t.plan(1)
const { FACETS, AGGREGATION_FILTER, AND } = global[indexName]
Expand All @@ -118,18 +133,50 @@ test('use AGGREGATION_FILTER with FACETS', t => {
}),
AND(['colour:Black'])
]).then(([facetResult, queryResult]) => {
t.deepEqual(
AGGREGATION_FILTER(facetResult, queryResult).filter(
item => item._id.length
),
[
{ FIELD: 'drivetrain', VALUE: 'Diesel', _id: [4] },
{ FIELD: 'drivetrain', VALUE: 'Petrol', _id: [1, 7] },
{ FIELD: 'model', VALUE: '3-series', _id: [7] },
{ FIELD: 'model', VALUE: '5-series', _id: [4] },
{ FIELD: 'model', VALUE: 'XC90', _id: [1] }
]
)
t.deepEqual(AGGREGATION_FILTER(facetResult, queryResult), [
{ FIELD: 'drivetrain', VALUE: 'Diesel', _id: [4] },
{ FIELD: 'drivetrain', VALUE: 'Petrol', _id: [1, 7] },
{ FIELD: 'model', VALUE: '3-series', _id: [7] },
{ FIELD: 'model', VALUE: '5-series', _id: [4] },
{ FIELD: 'model', VALUE: 'XC90', _id: [1] }
])
})
})

test('use AGGREGATION_FILTER with FACETS, keep empty facets', t => {
t.plan(1)
const { FACETS, AGGREGATION_FILTER, AND } = global[indexName]
Promise.all([
FACETS({
FIELD: ['drivetrain', 'model']
}),
AND(['Tesla'])
]).then(([facetResult, queryResult]) => {
t.deepEqual(AGGREGATION_FILTER(facetResult, queryResult, false), [
{ FIELD: 'drivetrain', VALUE: 'Diesel', _id: [] },
{ FIELD: 'drivetrain', VALUE: 'Electric', _id: [5, 6] },
{ FIELD: 'drivetrain', VALUE: 'Hybrid', _id: [] },
{ FIELD: 'drivetrain', VALUE: 'Petrol', _id: [] },
{ FIELD: 'model', VALUE: '3-series', _id: [] },
{ FIELD: 'model', VALUE: '5-series', _id: [] },
{ FIELD: 'model', VALUE: 'S', _id: [6] },
{ FIELD: 'model', VALUE: 'X', _id: [5] },
{ FIELD: 'model', VALUE: 'XC60', _id: [] },
{ FIELD: 'model', VALUE: 'XC90', _id: [] }
])
})
})

test('use AGGREGATION_FILTER with FACETS, 0-hit query', t => {
t.plan(1)
const { FACETS, AGGREGATION_FILTER, AND } = global[indexName]
Promise.all([
FACETS({
FIELD: ['drivetrain', 'model']
}),
AND(['colour:Black', 'colour:Diesel'])
]).then(([facetResult, queryResult]) => {
t.deepEqual(AGGREGATION_FILTER(facetResult, queryResult), [])
})
})

Expand Down Expand Up @@ -167,3 +214,26 @@ test('use AGGREGATION_FILTER with BUCKETS', t => {
])
})
})

test('use AGGREGATION_FILTER with BUCKETS', t => {
t.plan(1)
const { BUCKETS, AGGREGATION_FILTER, AND } = global[indexName]
Promise.all([
BUCKETS({
FIELD: ['year'],
VALUE: {
GTE: 3000,
LTE: 3010
}
}),
AND(['colour:Black'])
]).then(([facetResult, queryResult]) => {
t.deepEqual(AGGREGATION_FILTER(facetResult, queryResult, false), [
{
FIELD: ['year'],
VALUE: { GTE: 3000, LTE: 3010 },
_id: []
}
])
})
})

0 comments on commit ab7ded3

Please sign in to comment.