Multilevel index

Can I query with a multilevel term in index? E.g:

{
  name: "shiftByManager",
  unique: false,
  serialized: true,
  source: "Shift",
  terms: [
    {
      field: ["data", "user", "manager"]
    }
  ]
}

This way I can query all shifts of all employees which belong to a manager. For now, I have to make filter query, which is slow.

Any help would be appreciated.

Hi Thang,

Yes, this is supported in Fauna. For example, suppose we have the following records for a manager and an employee:

{
 ref: Ref(Collection("employees"), "304014359787471426"),
 ts: 1626189599380000,
 data: {
   name: "Alice Doe",
   title: "manager",
   reports: [Ref(Collection("employees"), "304014403131408962")]
 }
}

{
 ref: Ref(Collection("employees"), "304014403131408962"),
 ts: 1626189678070000,
 data: {
   name: "Bob Doe",
   title: "worker",
   user: {
     manager: Ref(Collection("employees"), "304014359787471426")
   }
 }
}

And this index for looking up the manager:

{
 ref: Index("employee_by_manager"),
 ts: 1626189798520000,
 active: true,
 serialized: true,
 name: "employee_by_manager",
 unique: false,
 source: Collection("employees"),
 terms: [
   {
     field: ["data", "user", "manager"]
   }
 ],
 values: [
   {
     field: ["data", "name"]
   }
 ],
 partitions: 1
}

Then running the index gives us:

Paginate(Match(Index("employee_by_manager"), Ref(Collection("employees"),"304014359787471426")))
{
  data: ["Bob Doe"]
}

Cory

1 Like

Hi Cora,

I don’t think what you suggested suits my case. Please consider 3 documents below

{
  "ref": Ref(Collection("User"), "302301519855747592"),
  "ts": 1625628452860000,
  "data": {
    "name": "Viet Thang"
  }
}

{
  "ref": Ref(Collection("User"), "302635559229063691"),
  "ts": 1624874610130000,
  "data": {
    "name": "Dep Trai",
    "manager": Ref(Collection("User"), "302301519855747592")
  }
}

And the document for Shift

{
  "ref": Ref(Collection("WorkShift"), "303555370245161484"),
  "ts": 1625903648910000,
  "data": {
    "user": Ref(Collection("User"), "302635559229063691"),
    "checkIn": Time("2021-07-10T13:12:29.420436Z"),
    "checkOut": Time("2021-07-10T14:54:07.575852Z")
  }
}

I found that this case can be done via bindings.

Thanks for your support btw

This might be the right place to use the Join function.

Index binding must be pure, one effect of which is that you cannot read additional documents in the binding (full list of disallowed functions in bindings in the docs).

That said, you can still do this without Filter. Thats where Join comes in.

Consider two indexes. One to get all the users with a given manager, and another for all of the shifts with a given user.

CreateIndex({
  name: "usersByManager",
  source: "User",
  terms: [
    { field: ["data", "manager"] }
  ]
})

CreateIndex({
  name: "shiftByUser",
  source: "WorkShift",
  terms: [
    { field: ["data", "user"] }
  ]
})

You can use Join to get the list of users and feed that into the shiftByUser Index.

Paginate(
  Join(
    Match(Index("usersByManager"), Ref(Collection("User"), "302301519855747592")),
    Index("shiftByUser")
  )
)

Hi @ThangVuNguyenViet. Were you able to get your application working how you wanted?