Search code examples
faunadb

How to get a set of not null documents in FaunaDB


I am going along this official tutorial and I create a similar index.

Below is my code that calculate the difference of a start and an end, which end is nullable.

CreateIndex({
  name: "foo_index",
  source: {
    collection: Collection("bar_collection"),
    fields: {
      interval: Query(
        Lambda(
          "bazDoc",
          If(
            Or(
              IsNull(Select(["data", "start"], Var("bazDoc"), null)),
              IsNull(Select(["data", "end"], Var("bazDoc"), null))
            ),
            null,
            Subtract(
              Select(["data", "end"], Var("bazDoc")),
              Select(["data", "start"], Var("bazDoc"))
            )
          )
        )
      )
    }
  },
  values: [
    { binding: "interval"},
    { field: ["ref", "id"]}
  ]
})

This is the return, which I want to filter out all docs that the interval is null. How should I achieve this.

{
  data: [
    [9, "353542771515064533"],
    [10, "353542807600758997"],
    [null, "353542787197567188"],
    [null, "353542814197350613"]
  ]
}

Btw, I'm new to FaunaDB, please suggest some resources to learn other than Fauna's own document.


Solution

  • The docs state

    When a document is indexed, and all of the index’s defined values evaluate to null, no index entry is stored for the document.

    Since you are also including the ref ID, which is never null, there will always be an index entry created.

    However, you can add another binding that also returns null in case the interval is null or the Ref otherwise. This way, both values will be null, and no entry will be created.

    
    CreateIndex({
      name: "foo_index",
      source: {
        collection: Collection("bar_collection"),
        fields: {
          interval: Query(
            Lambda(
              "bazDoc",
              If(
                Or(
                  IsNull(Select(["data", "start"], Var("bazDoc"), null)),
                  IsNull(Select(["data", "end"], Var("bazDoc"), null))
                ),
                null,
                Subtract(
                  Select(["data", "end"], Var("bazDoc")),
                  Select(["data", "start"], Var("bazDoc"))
                )
              )
            )
          ),
          ref: Query(
            Lambda(
              "bazDoc",
              If(
                Or(
                  IsNull(Select(["data", "start"], Var("bazDoc"), null)),
                  IsNull(Select(["data", "end"], Var("bazDoc"), null))
                ),
                null,
                Select(["ref"], Var("bazDoc"))
              )
            )
          )
        }
      },
      values: [
        { binding: "interval" },
        { binding: "ref" }
      ]
    })
    

    I’ve included the whole Ref as the value here, which is what I recommend. It makes it easier to reuse in combination with other queries, and all the drivers let you use the Ref values in additional queries and get the ID like ref.id in your app where you need it.

    please suggest some resources to learn other than Fauna's own document.

    I hope that others can also pitch in here, too. I am on the Customer Support team at Fauna and want to highlight that we have discourse forums and a discord server. Myself and other Fauna employees make a best effort to see that every forums question is addressed in a reasonable time, either by the community, or by answering ourselves; and we’re active in discord, which is better for general discussions.