Subset Search

I am looking to perform subset search so I can fully support my application that uses ABAC. I have a pipeline configured with the attributes required to access the objects. For example, I might have

{
  "department": "engineering",
  "location": "usa",
  "role": "developer"
}

If I have users on my end that have these attributes, I want them to be able to query and objects in a collection with any subset of these attributes, such as:

{
  "department": "engineering"
}
---
{
  "location": "usa"
}
---
{
  "department": "engineering",
  "location": "usa"
}
---

However, the entire collection of attributes is not known at query time. The ONLY information I have is the user attributes and the object attributes and need to return all objects who property values are a subset of the user’s attributes. Anyone know a way to do this?

Thanks in advance!

hi @coppetaj !!

Welcome to our community :hugs:

Let me know if this is what you are looking for:

client.collections.delete("AbaCollection")
collection = client.collections.create("AbaCollection")
collection.data.insert({
    "text": "engineering usa developer", 
    "department": "engineering",
    "location": "usa",
    "role": "developer"
})
collection.data.insert({
    "text": "marketing usa manager", 
    "department": "marketing",
    "location": "usa",
    "role": "manager"
})
# now one with different location
collection.data.insert({
    "text": "engineering uk developer", 
    "department": "engineering",
    "location": "uk",
    "role": "developer"
})

Now we can do some dynamic filtering:

from weaviate.classes.query import Filter

attributes = {
  "role": "manager"
}

available_properties = [p.name for p in collection.config.get().properties]

dynamic_filter = []
for k,v in attributes.items():
    if k in available_properties:
        dynamic_filter.append(
            Filter.by_property(k).equal(v)
        )
print("Dynamic filter:", dynamic_filter)
query_result = collection.query.fetch_objects(
    filters=Filter.any_of(dynamic_filter),
    limit=10
)
print("Found ", len(query_result.objects), " objects:")
print(query_result)

this should be the outcome:

Dynamic filter: [_FilterValue(value='manager', operator=<_Operator.EQUAL: 'Equal'>, target='role')]
Found  1  objects:
QueryReturn(objects=[Object(uuid=_WeaviateUUIDInt('7b97d568-0e5b-43d5-b36a-4b13b12072fc'), metadata=MetadataReturn(creation_time=None, last_update_time=None, distance=None, certainty=None, score=None, explain_score=None, is_consistent=None, rerank_score=None), properties={'text': 'marketing usa manager', 'department': 'marketing', 'location': 'usa', 'role': 'manager'}, references=None, vector={}, collection='AbaCollection')])

Let me know if this helps!

Thanks!