Filter nested array values that only has hits

Hello everyone! :innocent:

I am fairly new to Algolia and so far loving the experience. But I stucked with a problem, and simple googling and toggling Index Configuration did not help.

Example of my data:

{
objectID: "asd-asd-asd"
_type: "page",
title: "fruits",
modules: [
 {
  _id: "1",
  title: "mango",
  _type: "mango_module"
  description: "sweet and tasty",
  text: "long text"
 },
 {
  _id: "2",
  title: "apple",
  _type: "apple_module",
  description: "round",
  text: "long text"
 },
// ...
]
}

Imagine, that search query is “apple”. Result object must be:

{
objectID: "asd-asd-asd"
_type: "page",
title: "fruits",
modules: [
 {
  _id: "2",
  _type: "apple_module"
  title: "apple",
  description: "round",
  text: "long text"
 }
]
}

Response object should return “page” object, but filter out all values from “modules” array which did not “hit” the search query. If search query is “long text”, modules array must contain both “apple” and “mango”, because they both have text: "long text"

It also would be great, if there is a hit on “page” string property, to return all modules without filtering, but it’s not crusial, I think.

I would appreciate any help, and answer every question! Thanks to everyone in advance!

@Mehoff welcome to the community!

Unfortunately, this is a limitation with nested objects, however, you can solve this by separating out your modules into individual records and referencing the parent within the record instead.

For example:

[
  {
    "objectID": "module-1",
    "title": "mango",
    "_type": "mango_module",
    "description": "sweet and tasty",
    "text": "long text",
    "parent": {
      "objectID": "asd-asd-asd",
      "_type": "page",
      "title": "fruits"
    }
  },
  // ...
]

Alternatively, it would be possible to filter out those other modules using transformItems if you are using one of our InstantSearch libraries. It’s also possible to filter them out using our API Clients, but I can give more information on those if you need it.

Happy to help further, let us know! Thanks!

Hello Michael! Thank you for fast answer!
If you got time, and I am not too annoying at this point, I would love to see a filter using API Client. We are using algoliasearch Node.js package on front-end.

@Mehoff

If you are using an API Client, we can just modify the hits as they come over. Something like this should work:

index.search('mango')
    .then(({ hits }) => {
        hits.forEach(hit => {
            hit.modules = hit.modules.filter((moduleHit, moduleHitIndex) => {
                return moduleHit.title !== hit._highlightResult.modules[moduleHitIndex].title.value
            })
        })

        console.log(JSON.stringify(hits, null, 2))
    })
    .catch(err => console.error(err))

This would filter out any modules where the titles didn’t match. This is a quite limited implementation but you could adjust it to check any of the fields you would want.

Happy to help further, let us know! Thanks!