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.

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)))))
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]]]
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}}]}
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!