Why does an array in an index value return as null?

After trying to help @PaulieScanlon in this thread I noticed a weird behavior.

When having an object such as this:

{
  ref: Ref(Collection("TestArrays"), "269156828710961670"),
  ts: 1592946804640000,
  data: {
    slug: "hello-world",
    someArray: [
      {
        name: "Foo"
      },
      {
        name: "Bar"
      }
    ]
  }
}

And this index:

CreateIndex({
  name: "get_all_Things_by_slug",
  source: Collection("TestArrays"),
  terms: [
    {field: ["data", "slug"]}
  ],
  values: [
    {field: ["ref"]},
    {field: ["data", "slug"]},
    {field: ["data", "someArray"]}
  ]
})

The someArray value returns null:

Paginate(Match(Index("get_all_Things_by_slug"), "hello-world"))

{
  data: [
    [Ref(Collection("TestArrays"), "269156828710961670"), "hello-world", null]
  ]
}

Is this because Fauna can’t really use an array to sort the results?

It’s because we only index scalar values. Objects are not scalars. This is noted in the index documentation, but perhaps it could be clearer.

1 Like

Ah right.

Thanks @ben !

It makes a lot of sense when considering that indexes are “pre-calculated”, so to speak, but somehow I always imagine indexes going to the documents on every execution (which doesn’t make any sense but that’s how I tend to picture it).

It somewhat an artificial restriction (which is good news, we haven’t painted ourselves into any architectural corners on that front). We could do it if we had a universal ordering on objects for instance, or if we could say “inline this object, but it doesn’t participate in sorting”. There is work on going to design more expansive use of indexes, but for the moment indexed values have to be scalars.

1 Like

I also did a quick dig after the previous question.

Docs says, “Index terms are always scalar values…”, but I do not see anything about values that suggests this should be the case.

Yeah, that’s fair. I’ll circle back with docs to make sure this is a bit more obvious.

2 Likes

Hi @pier this is exactly the issue I ran into. I’ve tried a few of you suggestions and using a Lambda seems to work. Do you have a more complete example of how you’ve resolved your issue so I can check it against mine.

I’ve still got GraphQL issues but I think that’s separate to this Fauna array question.

Hey @PaulieScanlon !

Using Lambda is the standard way of getting an array of documents from an array of references provided by an index.

Like I mentioned in the other thread, if you know in advance you will only ever have a single document for each slug, you can create an index like this:

CreateIndex({
  name: "Things_by_slug",
  source: Collection("Things"),
  terms: [
    {field: ["data", "slug"]}
  ],
  unique: true
})

And query it like this without Lambda to get your document:

Get(Match(Index("Things_by_slug"), "some_slug"))
1 Like

Just to be clear and complete, it would work if your objects look like:

{
  ref: Ref(Collection("TestArrays"), "269156828710961670"),
  ts: 1592946804640000,
  data: {
    slug: "hello-world",
    someArray: [ "Foo", "Bar"]
  }
}

Arrays are ‘unrolled’ (if you can call it like that). But the value they contain have to be scalar.
So I think a more complete answer is that it has to be a scalar or an array of scalars.

2 Likes