UniqueQL Query Language
UniqueQL is an advanced query language designed to enhance search capabilities within the Unique AI platform. It enables powerful metadata filtering for vector search, full-text search, and combined search modes.
Overview
UniqueQL allows you to filter search results by metadata attributes such as:
- File names and paths
- URLs and document sources
- Dates and timestamps
- Custom metadata fields
- Folder hierarchies
- Document properties
The query language is versatile and can be translated into different query formats for various database systems, including PostgreSQL and Qdrant.
Importing UniqueQL
from unique_sdk import UQLOperator , UQLCombinator
Query Structure
A UniqueQL query consists of three components:
Path : Specifies the metadata attribute to filter (e.g., ["title"], ["year"], ["folderIdPath"])
Operator : Defines the type of comparison (e.g., EQUALS, CONTAINS, GREATER_THAN)
Value : Provides the criteria for the filter
Operators
Comparison Operators
EQUALS - Exact match
{
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2024"
}
NOT_EQUALS - Exclude value
{
"path" : [ "status" ],
"operator" : UQLOperator . NOT_EQUALS ,
"value" : "archived"
}
CONTAINS - Substring match
{
"path" : [ "title" ],
"operator" : UQLOperator . CONTAINS ,
"value" : "report"
}
NOT_CONTAINS - Exclude substring
{
"path" : [ "title" ],
"operator" : UQLOperator . NOT_CONTAINS ,
"value" : "draft"
}
Numeric and Date Operators
These operators work with both numbers and dates (ISO 8601 format).
GREATER_THAN - Numeric comparison
{
"path" : [ "size" ],
"operator" : UQLOperator . GREATER_THAN ,
"value" : 1000
}
GREATER_THAN - Date comparison
{
"path" : [ "createdAt" ],
"operator" : UQLOperator . GREATER_THAN ,
"value" : "2024-01-01T00:00:00Z"
}
LESS_THAN_OR_EQUAL - Numeric range filtering
{
"path" : [ "pageCount" ],
"operator" : UQLOperator . LESS_THAN_OR_EQUAL ,
"value" : 50
}
LESS_THAN - Date filtering
{
"path" : [ "updatedAt" ],
"operator" : UQLOperator . LESS_THAN ,
"value" : "2024-12-31T23:59:59Z"
}
List Operators
IN - Match any value in list
{
"path" : [ "department" ],
"operator" : UQLOperator . IN ,
"value" : [ "Engineering" , "Sales" , "Marketing" ]
}
NOT_IN - Exclude values
{
"path" : [ "category" ],
"operator" : UQLOperator . NOT_IN ,
"value" : [ "internal" , "draft" ]
}
Null/Empty Operators
IS_NOT_NULL - Exclude null values
{
"path" : [ "author" ],
"operator" : UQLOperator . IS_NOT_NULL ,
"value" : None
}
IS_NOT_EMPTY - Exclude empty values
{
"path" : [ "description" ],
"operator" : UQLOperator . IS_NOT_EMPTY ,
"value" : None
}
Combinators
Use AND and OR combinators to build complex queries:
AND - All conditions must match
{
UQLCombinator . AND : [
{
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2024"
},
{
"path" : [ "department" ],
"operator" : UQLOperator . EQUALS ,
"value" : "Engineering"
}
]
}
OR - Any condition can match
{
UQLCombinator . OR : [
{
"path" : [ "status" ],
"operator" : UQLOperator . EQUALS ,
"value" : "published"
},
{
"path" : [ "status" ],
"operator" : UQLOperator . EQUALS ,
"value" : "reviewed"
}
]
}
Complex Queries
Nested Queries - Filter nested metadata structures
Use NESTED operator for filtering within nested metadata structures:
from unique_sdk import UQLOperator , UQLCombinator
metadata_filter = {
"path" : [ 'diet' , '*' ],
"operator" : UQLOperator . NESTED ,
"value" : {
UQLCombinator . OR : [
{
UQLCombinator . OR : [
{
"path" : [ 'food' ],
"operator" : UQLOperator . EQUALS ,
"value" : "meat" ,
},
{
"path" : [ 'food' ],
"operator" : UQLOperator . EQUALS ,
"value" : "vegetables" ,
},
],
},
{
"path" : [ 'likes' ],
"operator" : UQLOperator . EQUALS ,
"value" : True ,
},
],
},
}
Combining AND and OR - Complex filter logic
metadata_filter = {
UQLCombinator . AND : [
{
"path" : [ "title" ],
"operator" : UQLOperator . CONTAINS ,
"value" : "report"
},
{
UQLCombinator . OR : [
{
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2024"
},
{
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2023"
}
]
}
]
}
Common Use Cases
Filter by Folder Path
metadata_filter = {
"path" : [ "folderIdPath" ],
"operator" : UQLOperator . CONTAINS ,
"value" : "uniquepathid://scope_engineering_docs"
}
search = unique_sdk . Search . create (
user_id = user_id ,
company_id = company_id ,
searchString = "API documentation" ,
searchType = "COMBINED" ,
metaDataFilter = metadata_filter
)
Filter by Date Range
Date operators work with ISO 8601 date strings. You can use dates with or without time:
# Date range filter
metadata_filter = {
UQLCombinator . AND : [
{
"path" : [ "createdAt" ],
"operator" : UQLOperator . GREATER_THAN_OR_EQUAL ,
"value" : "2024-01-01" # Date only
},
{
"path" : [ "createdAt" ],
"operator" : UQLOperator . LESS_THAN_OR_EQUAL ,
"value" : "2024-12-31" # Date only
}
]
}
# Or with full timestamp
metadata_filter = {
UQLCombinator . AND : [
{
"path" : [ "updatedAt" ],
"operator" : UQLOperator . GREATER_THAN ,
"value" : "2024-01-01T00:00:00Z" # Full ISO 8601
},
{
"path" : [ "updatedAt" ],
"operator" : UQLOperator . LESS_THAN ,
"value" : "2024-12-31T23:59:59Z"
}
]
}
Filter by Multiple Departments
metadata_filter = {
"path" : [ "department" ],
"operator" : UQLOperator . IN ,
"value" : [ "Engineering" , "Product" , "Design" ]
}
Exclude Specific Documents
metadata_filter = {
UQLCombinator . AND : [
{
"path" : [ "status" ],
"operator" : UQLOperator . EQUALS ,
"value" : "published"
},
{
"path" : [ "category" ],
"operator" : UQLOperator . NOT_IN ,
"value" : [ "internal" , "draft" ]
}
]
}
Using with Search API
Pass the metadata filter to the Search.create method
from unique_sdk import UQLOperator , UQLCombinator
# Build filter
metadata_filter = {
UQLCombinator . AND : [
{
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2024"
},
{
"path" : [ "department" ],
"operator" : UQLOperator . CONTAINS ,
"value" : "engineering"
}
]
}
# Use in search
search_results = unique_sdk . Search . create (
user_id = user_id ,
company_id = company_id ,
chatId = chat_id ,
searchString = "project updates" ,
searchType = "COMBINED" ,
metaDataFilter = metadata_filter ,
limit = 30
)
Using with Content API
UniqueQL filters can also be used with the Content API
content_info_result = unique_sdk . Content . get_infos (
user_id = user_id ,
company_id = company_id ,
metadataFilter = {
"or" : [
{
"and" : [
{
"operator" : "contains" ,
"path" : [ "folderIdPath" ],
"value" : "uniquepathid://scope_abcdibgznc4bkdcx120zm5d"
},
{
"operator" : "contains" ,
"path" : [ "title" ],
"value" : "ai"
}
]
}
]
},
skip = 0 ,
take = 3 ,
)
Best Practices
Combine Filters Efficiently
Use AND for restrictive filters and OR for inclusive filters
# Restrictive: Must match all
{
UQLCombinator . AND : [
{ "path" : [ "year" ], "operator" : UQLOperator . EQUALS , "value" : "2024" },
{ "path" : [ "status" ], "operator" : UQLOperator . EQUALS , "value" : "published" }
]
}
# Inclusive: Match any
{
UQLCombinator . OR : [
{ "path" : [ "department" ], "operator" : UQLOperator . EQUALS , "value" : "Engineering" },
{ "path" : [ "department" ], "operator" : UQLOperator . EQUALS , "value" : "Product" }
]
}
Test Filters Incrementally
Build complex filters step by step
# Start simple
filter1 = {
"path" : [ "year" ],
"operator" : UQLOperator . EQUALS ,
"value" : "2024"
}
# Add more conditions
filter2 = {
UQLCombinator . AND : [
filter1 ,
{
"path" : [ "status" ],
"operator" : UQLOperator . EQUALS ,
"value" : "published"
}
]
}
Complete Operator Reference
Operator
Description
Example Value Types
EQUALS
Exact match
String, Number, Boolean
NOT_EQUALS
Exclude exact match
String, Number, Boolean
CONTAINS
Substring match
String
NOT_CONTAINS
Exclude substring
String
GREATER_THAN
Greater than
Number, Date (ISO 8601)
GREATER_THAN_OR_EQUAL
Greater than or equal
Number, Date (ISO 8601)
LESS_THAN
Less than
Number, Date (ISO 8601)
LESS_THAN_OR_EQUAL
Less than or equal
Number, Date (ISO 8601)
IN
Match any value in list
Array
NOT_IN
Exclude values in list
Array
IS_NULL
Value is null
None
IS_NOT_NULL
Value is not null
None
IS_EMPTY
Value is empty
None
IS_NOT_EMPTY
Value is not empty
None
NESTED
Filter nested structures
Object
Next Steps
Now that you understand UniqueQL:
Try Search with Filters - Use UniqueQL in search queries
Explore Content API - Filter content with metadata
See Tutorials - View rule-based search tutorial
Read Full Documentation - Official UniqueQL documentation