# Collection filter for cache results

**URL:** <https://community.forestadmin.com/t/collection-filter-for-cache-results/2429>\
**Category:** Help me!\
**Tags:** howtos\
**Created:** [May 4, 2021, 2:44pm UTC](https://community.forestadmin.com/t/collection-filter-for-cache-results/2429 "2021-05-04T14:44:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vasilii](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/vasilii/32/976_2.png) [@Vasilii](https://community.forestadmin.com/u/Vasilii)\
**Post date:** [May 4, 2021, 2:44pm UTC](https://community.forestadmin.com/t/collection-filter-for-cache-results/2429/1 "2021-05-04T14:44:23Z")

</div>

In order to improve performance on a larger collection with complex business rules for loading items, we thought about introducing in-memory cache.

But there’s a problem with frequent filter condition updates: any time user adds and/or removes search conditions, that changes results of SQL and leads to the database queries.

Is there’s a way to somehow translate collection filter into predicate usable in Array.filter() or something like that?

---

<div class="post-metadata">

**Author:** ![morganperre](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/morganperre/32/1296_2.png) [@morganperre](https://community.forestadmin.com/u/morganperre)\
**Post date:** [May 4, 2021, 3:17pm UTC](https://community.forestadmin.com/t/collection-filter-for-cache-results/2429/2 "2021-05-04T15:17:10Z")

</div>

Hello @Vasilii !

Really great initiative. I’m currently making a [Woodshop](https://docs.forestadmin.com/woodshop/) article on Elasticsearch. We had a similar use case: How to translate filters generated from the Front to some filters comestible by Elasticsearch queries.

In you’re case you will have use our custom **filterTranslator** by changing the Elasticsearch logic on you’re own logic (function comestible by Array.filter() I presume).

Since the article is not released yet. I propose you to update this thread once it’s released. Or let me know if you need a code snippet really soon I will be able to give you that.

Have a nice day  
Morgan.

---

<div class="post-metadata">

**Author:** ![morganperre](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/morganperre/32/1296_2.png) [@morganperre](https://community.forestadmin.com/u/morganperre)\
**Post date:** [May 11, 2021, 9:23am UTC](https://community.forestadmin.com/t/collection-filter-for-cache-results/2429/3 "2021-05-11T09:23:01Z")

</div>

Hey @Vasilii,

We just release the [example on the filter translator](https://docs.forestadmin.com/woodshop/how-tos/create-a-smart-collection-with-elasticsearch/elasticsearch-service-utils#creating-utils-to-convert-express-query-filters-to-elasticsearch-one). I let you check this.

I just made this little example. It’s more of a pseudo-code but you get the idea.

```javascript
function equal(fieldDefinition, oneFilter) {
 return (record) => record[oneFilter.field] === oneFilter.value;
}

function greaterThan(fieldDefinition, oneFilter) {
 return (record) => record[oneFilter.field] > oneFilter.value;
}

function lessThan(fieldDefinition, oneFilter) {
 return (record) => record[oneFilter.field] < oneFilter.value;
}

const MAPPING = {
  equal,
  not_equal: not.bind(undefined, equal),
  greater_than: greaterThan,
  less_than: lessThan,
};

function mapFilter(fieldDefinitions, oneFilter) {
  const mapper = MAPPING[oneFilter.operator];
  const fieldDefinition = fieldDefinitions[oneFilter.field];

  if (!mapper) { throw new Error(`Unknown operator ${oneFilter.operator}, you need to define it !`); }
  if (!fieldDefinition) { throw new Error(`Unknown field ${oneFilter.field}, your field hasn't any field definition.`); }

  return mapper(fieldDefinition, oneFilter);
}

function translateFilter(fieldDefinitions, filters) {
  const noFilterFunction = (record) => record;
  if (!filters) { return noFilterFunction }

  if (!filters.aggregator) {
    return [mapFilter(fieldDefinitions, filters)];
  }

  const mapped = filters.conditions.map(
    mapFilter.bind(undefined, fieldDefinitions),
  );

  if (filters.aggregator === 'and') {
    return (record) => {
      return mapped.reduce((accumulator, currentValue) => {
        return accumulator && currentValue(record);
      }, record);
    }
  }

  return (record) => {
    return mapped.reduce((accumulator, currentValue) => {
      return accumulator || currentValue(record);
    }, record);
  }
}

```

---

<div class="post-metadata">

**Author:** ![Vasilii](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/vasilii/32/976_2.png) [@Vasilii](https://community.forestadmin.com/u/Vasilii)\
**Post date:** [May 19, 2021, 7:59am UTC](https://community.forestadmin.com/t/collection-filter-for-cache-results/2429/4 "2021-05-19T07:59:32Z")

</div>

@morganperre Hi, Morgan! Thanks for sharing, that’s a valuable piece of code 🤝
