Our API allows you to perform advanced searches using the filter
parameter as in GraphQL queries.
This tutorial will guide you through the process of writing these filters for your own purposes, using the sequence
entity as an example.
Understanding the Filter Object Structure
The filter
parameter accepts a JSON object that defines your search criteria. There are two main types of filters you can use:
Simple Filters: Quick and straightforward filters for common queries.
Expressive Filters: Advanced filters that allow for complex logical conditions.
Simple Filters
Simple filters are the quickest way to filter data based on direct field-value pairs. They are ideal for straightforward queries where you know exactly what you're looking for.
Structure:
{ "<field_name>": <value_or_array_of_values> }
Examples of Simple Filters
Filtering by Single Value
Goal: Retrieve sequences with a specific name.
{ "name": "My great sequence" }
Filtering by Multiple Values
Goal: Retrieve sequences with specific IDs.
{
"id": [
"c15a8f8d-ab8c-4c53-ac97-c512d5237aed",
"a36382a4-bd70-4b9a-a9ee-5477c9c00151",
"b3239647-aa05-4771-bff8-f80261c29133"
]
}
Filtering by Multiple Fields
Goal: Retrieve sequences that are circular and of type OLIGO
{ "circular": false, "sequenceTypeCode": "OLIGO"}
Expressive Filters
Expressive filters provide a more advanced way to construct complex queries using logical conditions and operators. They are useful when you need to write complex conditions, combine multiple conditions or apply nested logical operators.
Structure of Expressive Filters
An expressive filter is a JSON object that includes a root node with the following keys:
__objectType
: Specifies the type of the object, typically"query"
.type
: Specifies the type of the node, the first node usually"root"
.entity
: The name of the entity you are querying, e.g.,"sequence"
.filters
: An array of filter conditions or groups that define your query criteria.
Overall Structure:
{
"__objectType": "query",
"type": "root",
"entity": "<entity_name>",
"filters": [<filter_conditions_or_groups>]
}
Example of Root Node in an Expressive Filter:
The following filter root node can be used for getting records from the sequence entity:
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
...
]
}
Creating Basic Expressive Filters
In expressive filters, each condition is defined within the filters
array of the root node.
Expression Filters
An expression filter allows you to compare a field to a value using an operator.
Structure:
{
"type": "expression",
"operator": "<operator>",
"field": "<field_name>",
"args": [<value>]
}
Operators:
"equals"
"notEquals"
"greaterThan"
"lessThan"
"greaterThanOrEqual"
"lessThanOrEqual"
"contains"
(for strings and arrays)
Example: The following filter gets all sequences of sizes greater than 100:
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{ "type": "expression",
"operator": "greaterThan",
"field": "size",
"args": [100]
}
]
}
Example: Filter sequences which name field contains "construct" word
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "expression",
"operator": "contains",
"field": "name",
"args": [
"construct"
]
}
]
}
Example: Filter sequences which contains a feature with the name "operator O2"
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "expression",
"operator": "contains",
"field": "sequenceFeatures.name",
"args": [
"operator O2"
]
}
]
}
Where Filters
A where filter directly specifies field-value pairs for equality comparison.
Structure:
{ "type": "where", "args": { "<field_name>": <value> } }
Example: Get circular sequences which materials are tagged as externally available
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "where",
"args": {
"circular": true,
"polynucleotideMaterial.externalAvailability": true
}
}
]
}
Combining Filters with Logical Groups
To create more complex queries, you can combine multiple filters using logical operators ("and"
and "or"
) within group filters. These group filters are included within the filters
array of the root node.
Structure:
{
"__objectType": "query",
"type": "root",
"entity": "<entity_name>",
"filters": [
{
"type": "group",
"operator": "<logical_operator>",
"filters": [<filter_conditions_or_groups>]
}
]
}
Example: Combining Filters with AND
Goal: Find sequences that are larger than 500 bp and circular.
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "group",
"operator": "and",
"filters": [
{
"type": "expression",
"operator": "greaterThan",
"field": "size",
"args": [
500
]
},
{
"type": "expression",
"operator": "equals",
"field": "circular",
"args": [
true
]
}
]
}
]
}
Example: Combining Filters with OR
Goal: Find sequences that are either LINEAR_DNA or have "PCR" in their name.
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "group",
"operator": "or",
"filters": [
{
"type": "expression",
"operator": "equals",
"field": "sequenceTypeCode",
"args": [
"LINEAR_DNA"
]
},
{
"type": "expression",
"operator": "contains",
"field": "name",
"args": [
"PCR"
]
}
]
}
]
}
Building Nested Filter Groups
You can nest groups within groups to handle complex logical conditions. Each nested group is included within the filters
array of its parent group.
Example: Complex Nested Filter
Goal: Find sequences that:
Are circular.
Are larger than 0 bp.
And (either internally available or externally available).
Filter:
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "group",
"operator": "and",
"filters": [
{
"type": "where",
"args": {
"circular": true
}
},
{
"type": "expression",
"operator": "greaterThan",
"field": "size",
"args": [
0
]
},
{
"type": "group",
"operator": "or",
"filters": [
{
"type": "expression",
"operator": "equals",
"field": "polynucleotideMaterial.internalAvailability",
"args": [
true
]
},
{
"type": "expression",
"operator": "equals",
"field": "polynucleotideMaterial.externalAvailability",
"args": [
true
]
}
]
}
]
}
]
}
Accessing Nested Fields
As you may have noted from previous examples, you can access nested fields (fields within related objects). When filtering on nested fields, use dot notation in the field
key of your expression filters.
Example: Retrieve sequences related with a sample named "My sample"
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "expression",
"operator": "contains",
"field": "polynucleotideMaterial.samples.name",
"args": [
"My sample"
]
}
]
}
Tips for Writing Effective Filters
Choose the Right Filter Type: Use simple filters for straightforward queries and expressive filters for complex conditions.
Include the Root Node: In expressive filters, always include the root node with
__objectType
,type
, andentity
keys.Validate Field Names: Ensure you're using the correct field names as defined in the entity schema.
Select Appropriate Operators: Choose the operator that best fits your comparison needs.
Test Incrementally: Start with simple filters and gradually add complexity to ensure each part works as expected.
Proper JSON Formatting: Make sure your JSON structure is properly formatted to avoid syntax errors.
Common Use Cases
Using Simple Filters
Filtering by tags
Goal: Retrieve sequences tagged as "Important"
{
"taggedItems.tag.name": [
"Important"
]
}
Filtering by Exact Match
Goal: Find sequences named "Example Sequence".
{ "name": "Example Sequence" }
Using Expressive Filters
Filtering by Date Range
Goal: Find sequences created within the last month.
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "group",
"operator": "and",
"filters": [
{
"type": "expression",
"operator": "greaterThanOrEqual",
"field": "createdAt",
"args": [
"2024-08-01T00:00:00Z"
]
},
{
"type": "expression",
"operator": "lessThanOrEqual",
"field": "createdAt",
"args": [
"2024-08-30T23:59:59Z"
]
}
]
}
]
}
Using NOT Conditions
Goal: Find sequences that are not LINEAR_DNA.
{
"__objectType": "query",
"type": "root",
"entity": "sequence",
"filters": [
{
"type": "expression",
"operator": "notEquals",
"field": "sequenceTypeCode",
"args": [
"LINEAR_DNA"
]
}
]
}
Conclusion
By leveraging both simple and expressive filters, you can perform highly customized queries against the TeselaGen API. Simple filters are great for straightforward queries, while expressive filters provide the flexibility needed for complex conditions. Remember to include the root node with __objectType
, type
, and entity
in your expressive filters to ensure they are structured correctly. This powerful feature enables you to retrieve data that precisely matches your criteria, enhancing the efficiency and effectiveness of your data retrieval processes.
If you have any questions or need further assistance, please don't hesitate to reach out to our support team.