Open joepio opened 2 years ago
"Being able to ask graph-query-like questions would also help" - I have highly optimised data structure Terraphim Graph embeddings built specifically for this: https://github.com/terraphim/terraphim-ai/blob/0ccc42db4603047d86482f3e0cffed563d154bcf/crates/terraphim_pipeline/src/lib.rs#L96 I used to have it as a separate crate, but now the whole pipeline is a crate. If there is an interest, I can wrap it so embeddings will be embeddable into Atomic Server. I need a use case to drive it so we can create integration tests. The current design of graph queries is focused on precision - they are perfect for filtering out results before presenting them to the user. I also don't need language detection or stop words since the user is in full control of the graph. I am sharing Graph under Arc Mutex, but it's possible to make embeddings even better by simply Hash to turn it into an append-only data struct.
When users select something from a dropdown menu, we currently use hard-coded Collections to
atomicdata.dev
. For example, when adding aproperty
to acollection
, we searchhttps://atomicdata.dev/collections
.This works fine for modelling, but what if a user wants to:
In order to do this, we will need to find in collections that are probably scoped to some resource, probably a Drive. But there is no way we can perform these kinds of queries as of now.
Relates to #226
Ideally, we could set some Parent in a Collection, and find only items that have that resource as their parent.
So how would we implement this?
Some things to keep in mind:
Add
parent
attribute toQueryFilter
The
QueryFilter
is the fundamental building block of all indexes. If these have one parent, we can use that to set an extra filter. In many cases this will be theDrive
of the organization.But if a user wants to perform a more scoped search (parent scope instead of drive), this will not work.
Add
hierarchy
to keys inquery_index
A key looks something like this:
{QueryFilter} {sortedValue}
:{subject}
. This key design utilizes howBTreeMap
s are stored and sorted, because iterating over the keys gives us a nice, sorted list of results.We could utilize this principle too for doing filters.
For example, if we have resource
c
with a hierarchya > b > c
, and we want a hierarchy filter byb
. What do we store as key forc
?If the
QueryFilter
contains the parent hierarchy, we might get a lot of index duplication, because we might have a similar index for the same filters for the scopesa
andb
andc
.Instead of adding it to the
QueryFilter
, we could add it to the key:{QueryFilter} {hierarchy} {value}
If we do this we can easily get all the resources in a certain scope, but now the value is no longer sorted. This means we need to sort when iterating over the resources.
This approach should work well if there are not too many resources to be sorted, but it will fall apart if the number of sorted values becomes large. For example, if you want to sort all
Commit
s by date, it will become slow.We could also do
{QueryFilter} {sortedValue} {hierarchy}
Now filtering by hierarchy can be done when iterating over the resources. If the parent is not in the hierarchy, we skip it.
This works well if the items in the
{QueryFilter}
are relatively clustered. What I mean by this, is that the hierarchy items are relatively similar to each other. If the hierarchies are all over the place, the percentage ofskips
will often be large, and the query will be slow.Use Tantivy as index for everything
We already a parent / hierarchy filter in full-text search #226. Tantivy has this "facets" feature. It seems to offer all the features that our own store has. So we could use tantivy for all queries.
query_index
part. Less code, less maintenance.tantivy
toatomic_lib
if we do this. Or maybe move a lot of logic fromatomic_lib
toatomic_server
? Not sure what makes more sense.Make queries fundamentally more powerful
Being able to ask graph-query like questions would also help