List of terms

Problem

You want to search an index using a list of terms but Match only finds exact matches.

Solution

Map over the list of terms and then Union the results, which you can then Paginate over.

client.query(
  q.Map(
    q.Paginate(
      q.Union(
        q.Map(
          ['air', 'water'],
          q.Lambda(
            'element',
            q.Match(q.Index('spells_by_element'), q.Var('element'))
          )
        )
      )
    ),
    q.Lambda('ref', q.Get(q.Var('ref')))
  )
)
.then((ret) => console.log(ret))
.catch((err) => console.error(
  'Error: [%s] %s: %s',
  err.name,
  err.message,
  err.errors()[0].description,
))
{
  data: [
    {
      ref: Ref(Collection("spells"), "181388642046968320"),
      ts: 1627085181220000,
      data: {
        name: 'Fire Beak',
        element: [ 'air', 'fire' ],
        spellbook: Ref(Collection("spellbooks"), "181388642139243008")
      }
    },
    {
      ref: Ref(Collection("spells"), "181388642071085568"),
      ts: 1627085181220000,
      data: {
        name: "Water Dragon's Claw",
        element: [ 'water', 'fire' ],
        spellbook: Ref(Collection("spellbooks"), "181388642139243008")
      }
    },
    {
      ref: Ref(Collection("spells"), "181388642088911360"),
      ts: 1627085181220000,
      data: { name: "Hippo's Wallow", element: [ 'water', 'earth' ] }
    },
    {
      ref: Ref(Collection("spells"), "181388642581742080"),
      ts: 1627085181220000,
      data: { name: "Mountain's Thunder", element: 'air', cost: 15 }
    }
  ]
}
result = client.query(
  q.map_(
    q.lambda_("ref", q.get(q.var("ref"))),
    q.paginate(
      q.union(
        q.map_(
          q.lambda_(
            "element",
            q.match(q.index("spells_by_element"), q.var("element"))
          ),
          ["air", "water"]
        )
      )
    )
  )
)
print(result)
{'data': [{'ref': Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections))), 'ts': 1627085181220000, 'data': {'name': 'Fire Beak', 'element': ['air', 'fire'], 'spellbook': Ref(id=181388642139243008, collection=Ref(id=spellbooks, collection=Ref(id=collections)))}}, {'ref': Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections))), 'ts': 1627085181220000, 'data': {'name': "Water Dragon's Claw", 'element': ['water', 'fire'], 'spellbook': Ref(id=181388642139243008, collection=Ref(id=spellbooks, collection=Ref(id=collections)))}}, {'ref': Ref(id=181388642088911360, collection=Ref(id=spells, collection=Ref(id=collections))), 'ts': 1627085181220000, 'data': {'name': "Hippo's Wallow", 'element': ['water', 'earth']}}, {'ref': Ref(id=181388642581742080, collection=Ref(id=spells, collection=Ref(id=collections))), 'ts': 1627085181220000, 'data': {'name': "Mountain's Thunder", 'element': 'air', 'cost': 15}}]}
res, err := client.Query(
	f.Map(
		f.Paginate(
			f.Union(
				f.Map(
					f.Arr{"air", "water"},
					f.Lambda(
						"element",
						f.MatchTerm(
							f.Index("spells_by_element"),
							f.Var("element"),
						),
					),
				),
			),
		),
		f.Lambda("ref", f.Get(f.Var("ref"))),
	),
)

if err != nil {
	fmt.Fprintln(os.Stderr, err)
} else {
	fmt.Println(res)
}
map[data:[map[data:map[element:[air fire] name:Fire Beak spellbook:{181388642139243008 0xc000116540 0xc000116540 <nil>}] ref:{181388642046968320 0xc000116360 0xc000116360 <nil>} ts:1627085181220000] map[data:map[element:[water fire] name:Water Dragon's Claw spellbook:{181388642139243008 0xc000116900 0xc000116900 <nil>}] ref:{181388642071085568 0xc000116720 0xc000116720 <nil>} ts:1627085181220000] map[data:map[element:[water earth] name:Hippo's Wallow] ref:{181388642088911360 0xc000116ae0 0xc000116ae0 <nil>} ts:1627085181220000] map[data:map[cost:15 element:air name:Mountain's Thunder] ref:{181388642581742080 0xc000116cf0 0xc000116cf0 <nil>} ts:1627085181220000]]]
try
{
    Value result = await client.Query(
        Map(
            Paginate(
                Union(
                    Map(
                        Arr("air", "water"),
                        Lambda(
                            "element",
                            Match(
                                Index("spells_by_element"),
                                Var("element")
                            )
                        )
                    )
                )
            ),
            Lambda("ref", Get(Var("ref")))
        )
    );
    Console.WriteLine(result);
}
catch (Exception e)
{
    Console.WriteLine($"ERROR: {e.Message}");
}
ObjectV(data: Arr(ObjectV(ref: RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections"))),ts: LongV(1627085181220000),data: ObjectV(name: StringV(Fire Beak),element: Arr(StringV(air), StringV(fire)),spellbook: RefV(id = "181388642139243008", collection = RefV(id = "spellbooks", collection = RefV(id = "collections"))))), ObjectV(ref: RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections"))),ts: LongV(1627085181220000),data: ObjectV(name: StringV(Water Dragon's Claw),element: Arr(StringV(water), StringV(fire)),spellbook: RefV(id = "181388642139243008", collection = RefV(id = "spellbooks", collection = RefV(id = "collections"))))), ObjectV(ref: RefV(id = "181388642088911360", collection = RefV(id = "spells", collection = RefV(id = "collections"))),ts: LongV(1627085181220000),data: ObjectV(name: StringV(Hippo's Wallow),element: Arr(StringV(water), StringV(earth)))), ObjectV(ref: RefV(id = "181388642581742080", collection = RefV(id = "spells", collection = RefV(id = "collections"))),ts: LongV(1627085181220000),data: ObjectV(name: StringV(Mountain's Thunder),element: StringV(air),cost: LongV(15)))))
Map(
  Paginate(
    Union(
      Map(
        ["air", "water"],
        Lambda(
          "element",
          Match(Index("spells_by_element"), Var("element"))
        )
      )
    )
  ),
  Lambda("ref", Get(Var("ref")))
)
{
  data: [
    {
      ref: Ref(Collection("spells"), "181388642046968320"),
      ts: 1627085181220000,
      data: {
        name: "Fire Beak",
        element: ["air", "fire"],
        spellbook: Ref(Collection("spellbooks"), "181388642139243008")
      }
    },
    {
      ref: Ref(Collection("spells"), "181388642071085568"),
      ts: 1627085181220000,
      data: {
        name: "Water Dragon's Claw",
        element: ["water", "fire"],
        spellbook: Ref(Collection("spellbooks"), "181388642139243008")
      }
    },
    {
      ref: Ref(Collection("spells"), "181388642088911360"),
      ts: 1627085181220000,
      data: {
        name: "Hippo's Wallow",
        element: ["water", "earth"]
      }
    },
    {
      ref: Ref(Collection("spells"), "181388642581742080"),
      ts: 1627085181220000,
      data: {
        name: "Mountain's Thunder",
        element: "air",
        cost: 15
      }
    }
  ]
}
Query metrics:
  •    bytesIn:   220

  •   bytesOut: 1,125

  • computeOps:     1

  •    readOps:     6

  •   writeOps:     0

  •  readBytes:   643

  • writeBytes:     0

  •  queryTime:  13ms

  •    retries:     0

Discussion

Match returns a Set Reference, so when we Map over it, the result is an Array of set references. In order to Paginate, we need to Union the array back into a single set first.

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!