Join

Join( source, detail )
Join( source, detail )
Join( source, detail )
Join( source, detail )
join( source, detail )
Join( source, detail )

Description

The Join function finds all index tuples from the source SetRef and uses the source's values to be retrieved from the detail index terms.

The run time of Join is dependent on the number of elements in the underlying set or page — it’s linear, or O(n). For very large sets or pages, executing Join might result in a query timeout error, or "width" error.

For query "width" errors, the underlying set or page involves more than 100K items. This can happen when using a set function, such as Difference, where more than 100K items need to be considered to produce the set that Join evaluates. To resolve this, use Paginate to limit the set or page size.

For example, instead of:

Join(
  Difference(
    Match(Index("Index1"), "term1"),
    Match(Index("Index2"), "term2")
  )
)

use:

Join(
  Paginate(
    Difference(
      Match(Index("Index1"), "term1"),
      Match(Index("Index2"), "term2")
    ),
    { size: 10000 }
  )
)

This does mean that if the entire set must be evaluated to arrive at the correct result, you would have to page through the Paginate results.

For query timeout errors, you may specify a larger query timeout via the driver that you are using.

Parameters

Argument Type Definition and Requirements

source

The source SetRef for the join operation.

detail

IndexRef or Lambda function

The IndexRef to join with the source SetRef, or the Lambda function which determines how to complete the join operation.

Returns

The SetRef for the join operation.

Examples

The index form is useful when the documents in the source_set match the terms in an index. Join returns documents from an Index (specified by detail) that match the terms from source.

try
{
    Value result = await client.Query(
        Paginate(
            Join(
                Match(
                    Index("spellbooks_by_owner"),
                    Ref(Collection("characters"), "181388642114077184")
                ),
                Index("spells_by_spellbook")
            )
        )
    );
    Console.WriteLine(result);
}
catch (Exception e)
{
    Console.WriteLine($"ERROR: {e.Message}");
}
ObjectV(data: Arr(RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections"))), RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections")))))
result, err := client.Query(
	f.Paginate(
		f.Join(
			f.MatchTerm(
				f.Index("spellbooks_by_owner"),
				f.Ref(f.Collection("characters"), "181388642114077184")),
			f.Index("spells_by_spellbook"))))

if err != nil {
	fmt.Fprintln(os.Stderr, err)
} else {
	fmt.Println(result)
}
map[data:[{181388642046968320 0xc0001402a0 0xc0001402a0 <nil>} {181388642071085568 0xc000140450 0xc000140450 <nil>}]]
System.out.println(
    client.query(
        Paginate(
            Join(
                Match(
                    Index("spellbooks_by_owner"),
                    Ref(Collection("characters"), "181388642114077184")
                ),
                Index("spells_by_spellbook")
            )
        )
    ).get());
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))]}
client.query(
  q.Paginate(
    q.Join(
      q.Match(
        q.Index('spellbooks_by_owner'),
        q.Ref(q.Collection('characters'), '181388642114077184')
      ),
      q.Index('spells_by_spellbook'),
    )
  )
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{
  data: [
    Ref(Collection("spells"), "181388642046968320"),
    Ref(Collection("spells"), "181388642071085568")
  ]
}
result = client.query(
  q.paginate(
    q.join(
      q.match(
        q.index("spellbooks_by_owner"),
        q.ref(q.collection("characters"), "181388642114077184")
      ),
      q.index("spells_by_spellbook")
    )
  )
)
print(result)
{'data': [Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections))), Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections)))]}
try {
  println(Await.result(
    client.query(
  Paginate(
    Join(
      Match(
        Index("spellbooks_by_owner"),
        Ref(Collection("characters"), "181388642114077184")),
      Index("spells_by_spellbook")))),
    5.seconds
  ))
} catch {
  case unknown: Throwable => println("Error: " + unknown.getMessage())
}
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))]}

The Lambda form requires the Lambda function to be pure. i.e. it may not make any reads or writes.

try
{
    Value result = await client.Query(
        Paginate(
            Join(
                Match(
                    Index("spellbooks_by_owner"),
                    Ref(Collection("characters"), "181388642114077184")
                ),
                Lambda(
                    "spellbook",
                    Match(Index("spells_by_spellbook"), Var("spellbook"))
                )
            )
        )
    );
    Console.WriteLine(result);
}
catch (Exception e)
{
    Console.WriteLine($"ERROR: {e.Message}");
}
ObjectV(data: Arr(RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections"))), RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections")))))
result, err := client.Query(
	f.Paginate(
		f.Join(
			f.MatchTerm(
				f.Index("spellbooks_by_owner"),
				f.Ref(f.Collection("characters"), "181388642114077184"),
			),
			f.Lambda(
				"spellbook",
				f.MatchTerm(
					f.Index("spells_by_spellbook"),
					f.Var("spellbook"))))))

if err != nil {
	fmt.Fprintln(os.Stderr, err)
} else {
	fmt.Println(result)
}
map[data:[{181388642046968320 0xc00008e300 0xc00008e300 <nil>} {181388642071085568 0xc00008e4b0 0xc00008e4b0 <nil>}]]
System.out.println(
    client.query(
        Paginate(
            Join(
                Match(
                    Index("spellbooks_by_owner"),
                    Ref(Collection("characters"), "181388642114077184")
                ),
                Lambda(
                    Value("spellbook"),
                    Match(
                        Index("spells_by_spellbook"),
                        Var("spellbook")
                    )
                )
            )
        )
    ).get());
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))]}
client.query(
  q.Paginate(
    q.Join(
      q.Match(
        q.Index('spellbooks_by_owner'),
        q.Ref(q.Collection('characters'), '181388642114077184'),
      ),
      q.Lambda(
        'spellbook',
        q.Match(q.Index('spells_by_spellbook'), q.Var('spellbook')),
      )
    )
  )
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{
  data: [
    Ref(Collection("spells"), "181388642046968320"),
    Ref(Collection("spells"), "181388642071085568")
  ]
}
result = client.query(
  q.paginate(
    q.join(
      q.match(
        q.index("spellbooks_by_owner"),
        q.ref(q.collection("characters"), "181388642114077184")
      ),
      q.lambda_(
        "spellbook",
        q.match(
          q.index("spells_by_spellbook"),
          q.var("spellbook")
        )
      )
    )
  )
)
print(result)
{'data': [Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections))), Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections)))]}
try {
  println(Await.result(
    client.query(
  Paginate(
    Join(
      Match(
        Index("spellbooks_by_owner"),
        Ref(Collection("characters"), "181388642114077184")),
      Lambda { spellbook =>
        Match(Index("spells_by_spellbook"), spellbook)
      }))),
    5.seconds
  ))
} catch {
  case unknown: Throwable => println("Error: " + unknown.getMessage())
}
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))]}

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's Discourse forums or email docs@fauna.com

Thank you for your feedback!