Match to any value in Filter function if critereon not set

Hi
I’ve following query to get rooms of type of 'double':

Filter(
  Select('data',
    Paginate(
      Match(Index("by_room_type")))), 
      Lambda(['ref','v'], Equals(Var('v'), 'double')
    )
)

Issue is that I want the value 'double' to be any i.e. 'single' and if not specified then to all rooms without any specification. I tried like to get all:

Filter(
  Select('data',
    Paginate(
      Match(Index("by_room_type")))), 
      Lambda(['ref','v'], Equals(Var('v'), '*')
    )
)

But it’s not working.

Totally new to Fauna and actually, my need is to make a Search to get documents on request which have multiple criteria like string search, price, room type etc but sometimes if not needed to apply one criterion then it’d get all.
I thought of using if but don’t know which one is effective

Hi inam! Thanks for using Fauna.

The Equals function simply compares two values and returns true if they match. Fauna doesn’t have a wildcard version of Equals, so that strategy is not going to work. It might be possible to use ContainsStrRegex to good effect, though.

I’m guessing that the by_room_type index has no terms. It would be more efficient if you were using a index that specified the room type as a term. Something like this:

CreateIndex({
  name: "rooms_by_room_type",
  source: Collection("rooms"),
  terms: [
    { field: ["data", "room_type"] }
  ],
})

With that index, you can then get the references for all matching room types:

Paginate(Match(Index("rooms_by_room_type"), "double"))

If you need all rooms, regardless of room type, then you’d use:

Paginate(Documents(Collection("rooms")))

If you need to fetch some/all of the room details with those queries, you could revise the index to report them, or simply run a query like this:

Map(
  Paginate(Match(Index("rooms_by_room_type"), "double")),
  Lambda(
    "ref",
    Get(Var("ref"))
  )
)

Notice that inside the Map call, I’ve place the first Paginate example, which fetches a page of room with the “double” room type. Map then calls the Lambda on each entry in the page of results, and fetches the full document for the room.

This is an example of FQL’s composition capability, when the result from one function can be used as a parameter to another function.

If you need to search by two criteria, then you would create another index that could look like this:

CreateIndex({
  name: "rooms_by_room_type_and_price",
  source: Collection("rooms"),
  terms: [
    { field: ["data", "room_type"] },
    { field: ["data", "price"] },
  ],
})

Then you could fetch matching entries with:

Paginate(Match(Index("rooms_by_room_type_and_price"), "double", 80.00))

Fauna forces you to be more deliberate about your queries than SQL does, so that i can avoid resource problems that arise from open-ended queries and temporary results.

Thanks for such a nice response. Still I’m not able to get what I want to. I followed your second method and made an index and made query

CreateIndex({
  name: "rooms_by_room_type_and_price",
  source: Collection("allValues"),
  terms: [
    { field: ["data", "Room Type"] },
    { field: ["data", "Total # rooms"] },
  ],
})

then this query

Paginate(Match(Index("rooms_by_room_type_and_price"), "(double)", '2'))
{
  data: [
    Ref(Collection("allValues"), "3046813"),
    Ref(Collection("allValues"), "14927182"),
    Ref(Collection("allValues"), "15780422"),
    Ref(Collection("allValues"), "16057815"),
    Ref(Collection("allValues"), "16074230"),
    Ref(Collection("allValues"), "16075629")
  ]
}

But now how to get all with only setting one criteria like either Type or Total number? I tried

1. Paginate(Match(Index("rooms_by_room_type_and_price"), "", '2'))
2. Paginate(Match(Index("rooms_by_room_type_and_price"), "-", '2'))
3. Paginate(Match(Index("rooms_by_room_type_and_price"), , '2'))

but not working. How can I get all rooms only with total number '2' but doesn’t matter if type is ‘double’ or ‘single’? Or opposite to it?

The parameters that you pass to Match must match the parameters defined in the index, or no match occurs.

You should create indexes for each distinct matching scenario that your app requires.

Alternately, you could create an index on the one parameter that you use most often, and configure the index to return the other values that you commonly use as conditions. Then you can use a Filter expression to keep only the results that you need for the current query. That would make your queries perform more work, but would reduce the number of write ops incurred from having multiple indexes.