We can use indexes to build intricate relevance scores via a binding.
And we can use JOIN to relate different indexes or collections together.
However, if you want to build a relevance score that involves two indexes, there is no efficient way to do so.
For example, in a music database:
MUSIC_GENRE_BY_USER_AND_POPULARITY is an index that records how many times a user likes a particular genre.
From this, we can use a binding to calculate a genrePopScore with a time factor to answer the question “which genres does someone like the most and also most recently?”
Next we have another index SONGS_BY_GENRE
Which tells us the most popular songs in a genre with a similar time based songScore.
However, there is no way to combine the two scores efficiently.
What I really want is the genrePopScore x songScore which answers the question “which popular songs would this user really like?”
One way this could happen would be allowing index bindings to accept parameters.
So:
CreateIndex({
name: "SONGS_BY_GENRE",
source: {
collection: Collection("SONGS"),
fields: {
songScore: Query(
Lambda("ref", "genrePopScore"
Let({
songScoreCalc: //some algorithm,
},
Multiply(Var("songScoreCalc"),Var("genrePopScore"))
)
)
},
},
terms: [ field: ["data", "genre"],
values: [
//sort on songScore
{ binding: "songScore" },
{ field: "ref" }
],
});
The key line, and only change from existing FQL
being
Lambda("ref", "genrePopScore"
where genrePopScore would be passed through the call to Match
eg:
Match(
Index("SONGS_BY_GENRE"),
Ref("someGenre"),
0.83
)
It would still match against Ref("someGenre")
but the second parameter 0.83 would be available in the bindings (both values or terms).
This way you can Join
a Match
against MUSIC_GENRE_BY_USER_AND_POPULARITY to generate a genrePopScore and pass it through to the SONGS_BY_GENRE index to finally get your combined score sorted with the most relevant data at the top of the results.
This would be useful in any number of scenarios. Imagine a medical database where you want to create a score based on pharmaceuticals relevant to a particular person and cross reference it with information based on their genome to arrive at the most suitable remedy candidates.
Or…for a financial institution calculate a more relevant and accurate financial risk score tailored to each user.
And why stop at 2 collections? You can call Join as many times as you want to really create intricately cross-linked queries that answer all kinds of interesting relational questions.
As it currently stands, the kinds of Joins you can do in Fauna are somewhat narrow and limited and kind of black and white, and this improvement would open up a massive new way to extract and elucidate meaning from a database and provide access to all the shades of grey that exist, but currently cannot be revealed (efficiently, and at scale).