Index not returning results for property-in-array term

Given this schema:

collection TestArrayIndexing {
  index byPhoneNumberId {
    terms [.notificationPhoneNumbers.phoneNumberId]
  }
}

And this data:

TestArrayIndexing.create({
  notificationPhoneNumbers: [{
    phoneNumberId: 1
  }, {
    phoneNumberId: 2
  }]
})

I’d expect this call to return data, but it returns an empty set:

TestArrayIndexing.byPhoneNumberId(1)
1 Like

Based on the Indexing Docs

When an Array is indexed, an index entry is created for each of its elements.

I would’ve expect the following syntax to work

collection TestArrayIndexing {
  index byPhoneNumberId {
    terms [.notificationPhoneNumbers]
  }
}
TestArrayIndexing.byPhoneNumberId({ phoneNumber: 1 })

But we still get an empty set back ;-;


Interestingly enough, the following schema doesn’t return an empty set-

collection TestArrayIndexing {
  index byPhoneNumberId {
    terms [.notificationPhoneNumbers[0].phoneNumberId]
  }
}
TestArrayIndexing.byPhoneNumberId(1)

Not that it achieves what you’re looking for, just thought it was worth noting ( :

1 Like

That line in the docs is partially correct, but should be clarified. I’ve notified the docs team.

An array is indexed as a single, scalar value unless marked as a Multi-valued Attribute (MVA) by

  • (FQL) setting the index’s mva flag to true, or
  • (FSL) wrapping the term the mva() helper

IMPORTANT: MVA’s only works when the array is the LAST item in the field path. I.e. there is nothing magical about traversing field paths for index terms and values*. It works the same as though querying the field.

Consider here the path .notificationPhoneNumbers.phoneNumberId. This will always resolve to null because .notificationPhoneNumbers is an array, and arrays do not have a phoneNumberId field.

Instead, create a computed field to turn your complex object in to precisely the array you wish to index, and specify the index term as mva

collection TestArrayIndexing {
  // every term here resolves to `null` and no entries are created
  index byPhoneNumberId {
    terms [.notificationPhoneNumbers.phoneNumberId]
  }

  // use a computed field instead
  compute phoneNumberIds = (.notificationPhoneNumbers.map(.phoneNumberId))

  index byPhoneNumberId2 {
    terms [mva(.phoneNumberIds)]
  }

* NOTE: field paths when defining v4 indexes were kinda magic, as they would automatically map over arrays, but in v10 you have to be explicit with the field path.

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.