I’m looking for some best practice advice. Say I have 2 collections which are related, with 2 indexes. E.g:
// Book with id #1
Books.data = {
bookTitle: 'My book',
authorName: 'John Smith'
}
Publications.data = {
bookRef: Ref(Collection("Books"), '1'),
publicationCountry: "USA",
publicationTime: Time("2020-07-07T00:00:00Z")
}
// Indexes
CreateIndex({
name: 'Books.info_by_bookRef_authorName.sort_bookTitle',
terms: [
{field: ["ref"]},
{field: ["data", "authorName"]}
],
values: [
{field: ["data", "bookTitle"]},
{field: ["data", "authorName"]},
{field: ["ref"]}
]
})
CreateIndex({
name: 'Publications.by_country.sort_time',
terms: [{field: ['data', 'publicationTime']}],
values: [
{field: ["data", "publicationTime"], reverse: true},
{field: ["data", "publicationCountry"]},
{field: ["data", "bookRef"]},
{field: ["ref"]}
]
})
Now, say I want all publications (with book info) written by author “John Smith” published in “USA”. I can get this via Join
like so:
Let(
{
pubMatch: Match( // This gets all publications - even those you dont want to query
Index('Publications.by_country.sort_time'),
["USA"]
),
bookMatch: Join( // This filters down to only the relevant books
Var('pubMatch'),
Lambda(
['publicationTime', 'publicationCountry', 'bookRef', 'publicationRef'],
Match(
Index("Books.info_by_bookRef_authorName.sort_bookTitle"),
[Var('bookRef'), "John Smith"]
)
)
)
},
{
books: Paginate(
Var('bookMatch')
),
pubs: Paginate(Var('pubMatch'))
}
)
This returns something like:
{
books: {
data: [
["Booktitle1", "John Smith", Ref(Collection("Books"), "268585911116104199")],
["Booktitle2", "John Smith", Ref(Collection("Books"), "269113645096501765")],
["Booktitle3", "John Smith", Ref(Collection("Books"), "269113828661264903")],
["Booktitle4", "John Smith", Ref(Collection("Books"), "269129263220785669")],
["Booktitle5", "John Smith", Ref(Collection("Books"), "269401393804083717")]
]
},
pubs: {
data: [
[
Time("2020-07-02T07:30:49.870320Z"),
"USA",
Ref(Collection("Books"), "269127569049125381"),
Ref(Collection("Publications"), "269920449379435014")
],
[
Time("2020-07-01T09:12:44.386935Z"),
"USA",
Ref(Collection("Books"), "269304525234373126"),
Ref(Collection("Publications"), "269836263934132743")
],
[
Time("2020-07-01T08:46:33.172310Z"),
"USA",
Ref(Collection("Books"), "269401393804083717"),
Ref(Collection("Publications"), "269834616420958727")
],
[
Time("2020-06-27T13:08:22.443175Z"),
"USA",
Ref(Collection("Books"), "269113645096501765"),
Ref(Collection("Publications"), "269488700977578502")
],
[
Time("2020-06-26T12:23:54.997807Z"),
"USA",
Ref(Collection("Books"), "269129263220785669"),
Ref(Collection("Publications"), "269395306986078726")
],
[
Time("2020-06-26T07:59:30.311936Z"),
"USA",
Ref(Collection("Books"), "269113828661264903"),
Ref(Collection("Publications"), "269378671643460103")
],
[
Time("2020-06-17T14:09:37.552477Z"),
"USA",
Ref(Collection("Books"), "268585911116104199"),
Ref(Collection("Publications"), "268586403984572933")
]
]
}
}
Now - I only want the books
results obviously, but WITH the data from the first query…! What is the best practice to include the results from the publications in the results from books?
This is what I can come up with at the moment:
- Have a new index called “Publications.by_bookRef” which returns the desired data.
- Somehow call
ToObject(...)
on the paginated results to make the returned value subscriptible usingSelect()
on the Books’Ref()
- Map through the Book results and add items to the results using the aforementioned
Select()
method. - The above would only work IF there aren’t multiple Publications per Book - which isn’t logical in the above example…
This feels quite hacky, and it feels like I should already have the data available through the Index-Match I have already run?
Or maybe I should do this in a completely different way?