Home

Using Search with SDK

This page provides a comprehensive guide to using the powerful search functionality of the Tenyks platform through the SDK. The search interface allows for a range of filters and supports hybrid searches with similarity searches based on text and images.

Examples

1. Searching for Images with Pedestrians at Night

This example shows how to search for images containing pedestrians, while filtering out small annotations and ensuring the image was not tagged with daytime:day.

# Images with not too small pedestrians at night
search_result = dataset.search_images(
    filter="and(annotation_category:[pedestrian],not(or(annotation_width<50,annotation_height<50)),not(image_tag:[daytime_day]))",
)
display_images(search_result, n_images_to_show=10)

2. Similarity Search: Images of Taxis at Night

In this example, we perform a hybrid search using vector-text similarity to find images that match the word "taxi".

# Images with taxis at night (hybrid search)
search_result = dataset.search_images(
    sort_by="vector_text(taxi)",
)
display_images(search_result, n_images_to_show=10)

3. Hybrid Search: Images of Trucks and Buses during the Day with Blue Sky

Both approaches can be combined. In this example we search for images that contain annotated trucks and buses, in images tagged as daytime:day and are most similar to the text "blue sky".

search_result = dataset.search_images(
    filter="and(annotation_category:[truck,bus],image_tag:[daytime_day])",
    sort_by="vector_text(blue sky)"
)
display_images(search_result, n_images_to_show=10)

4. Use a Generator to Iterate over Search Results in a Paginated Manner

search_generator = dataset.images_generator(filter="annotation_category:[pedestrian]", page_size=20)
for i, im in enumerate(search_generator):
    print(f"Image {i}: {im}") # prints image metadata

Similarity Search Methods

The SDK supports various vector-based similarity searches to find images or objects similar to provided inputs. The available similarity search methods are:

Similarity TypeMethodDescriptionExample Usage
Text to Imagevector_text(text)Search for images that closely match the provided text.sort_by="vector_text(taxi)"
Image to Imagevector_image(image_keys)Search for images similar to images with the provided image key(s). Multiple image keys can be specified.sort_by="vector_image(image_key1, image_key2)"
Object Similarityvector_object(object_keys)Search for images containing objects similar to objects with the provided object key(s). Multiple object keys can be specified.sort_by="vector_object(object_key1, object_key2)"

📘

When working with the SDK, you can get the image key by accessing the .key attribute of an Image object (for example, the dataset.search_images method returns a list of Image. The same can be done for object with Annotation.id or Prediction.id.

Query Structure

📘

A query is represented by a Python string in the SDK.

Our query language follows a simple set of rules, similar to building blocks, that help you create complex searches. These rules explain how to combine Boolean logic (like and, or, not) with filters to retrieve exactly the data you want.

1. Query

Query: A query is a combination of conditions (filters) that are joined together using Boolean operators. You can think of it as a sentence that says, "I want this and that, but not this."

Query = Boolean Operator ( Subquery, Subquery, ... )
  • Example: and(condition1, condition2)
  • This means both condition1 and condition2 must be true.

2. Subquery

Subquery: A subquery is a smaller part of the main query. It can either be a simple filter or a more complex query (allowing you to "nest" conditions within other conditions).

Subquery = Filter | Query
  • Example: not(or(condition1, condition2))
  • This says neither condition1 nor condition2 should be true.

3. Boolean Operators

Boolean Operators🟥: These are the words that define how you combine filters. Think of them as "and", "or", and "not".

BooleanOperator = 'and' | 'or' | 'not'
  • and: All conditions must be true.

  • or: At least one condition must be true.

  • not: The condition must not be true.

  • Example: and(condition1, condition2) means both conditions must hold true for the result to be valid.

3. Filter

Filter: A filter is a basic condition that compares a field (like annotation_category, image_tag) to a specific value using an operation (like =, <, or in). This is where the actual filtering happens.

Filter = Filter Name Filter Operation Value
  • Example: annotation_category:[pedestrian]
  • This checks if the annotation_category is in the list [pedestrian].

4. Filter Name

Filter Name🟩: This is the name of the field you want to filter on, like annotation_category, annotation_width, or image_tag.

FilterName = The name of the field (e.g., annotation_category)
  • Example: annotation_width
  • This represents the width of an annotation.

5. Filter Operation

Filter Operation🟨: This defines the comparison you’re making, such as checking if something is equal, less than, or greater than a value.

FilterOperation = ':' | '<' | '>' | '<=' | '>=' | '='
  • Example: annotation_width<50
  • This checks if the annotation's width is less than 50.
  • Available operations:
    • = "equal"
    • < "less than"
    • <= "less than or equal"
    • > "greater than"
    • >= "greater than or equal"
    • : "in"

6. Value

Value🟦: This is the value you are comparing against, such as pedestrian for categories or 50 for a number.

Value = A number, text, or list of values
  • Example: 50 or [bus,truck]
  • This represents the value you’re checking against.

Putting It All Together

Now that you understand the building blocks, let's look at how to combine them into more complex queries.

Format Reminder:

Boolean Operator(Filter Name Filter Operation Value)

Example Query:

and(annotation_category:[pedestrian], not(or(annotation_width<50, annotation_height<50)))

Here’s how to interpret it:

  • Boolean Operator and: We want multiple conditions to be true.
  • Filter 1: annotation_category:[pedestrian] means we’re looking for annotations in the pedestrian category.
  • Subquery (nested query): not(or(annotation_width<50, annotation_height<50)) excludes any images where either the annotation width or the height is less than 50.
search_generator = dataset.images_generator(filter="annotation_category:[pedestrian]", page_size=20)
for i, im in enumerate(search_generator):
    print(f"Image {i}: {im}") # prints image metadata

Available Filters

The following filters are available for structuring queries:

Filter NameTypeSupported OperationsExample
image_filenameString=, :filter="image_filename:[filename1.jpg,filename2.jpg]"
image_keyString=, :filter="image_key:[img123,img456]"
image_formatString=, :filter="image_format:[jpg,png]"
image_widthNumeric=, <, <=, >, >=filter="image_width>=1920"
image_heightNumeric=, <, <=, >, >=filter="image_height<1080"
image_areaNumeric=, <, <=, >, >=filter="image_area>50000"
image_tagString:filter="image_tag:[key_value]"
filter="image_tag:[weather_sunny]"
annotation_idString=, :filter="annotation_id:[anno_01]"
annotation_categoryString:filter:"annotation_category:[pedestrian,traffic light]"
annotation_tagString:filter="image_tag:[key_value]"
filter="image_tag:[colour_red,colour_blue]"
annotation_widthNumeric=, <, <=, >, >=filter="annotation_width>100"
annotation_heightNumeric=, <, <=, >, >=filter="annotation_height<=200"
annotation_areaNumeric=, <, <=, >, >=filter="annotation_area>=10000"
annotation_x_locationNumeric=, <, <=, >, >=filter="annotation_x_location<500"
annotation_y_locationNumeric=, <, <=, >, >=filter="annotation_y_location>=300"
prediction_idString=, :filter="prediction_id:[pred_01]"
prediction_categoryString:filter="prediction_category:[vehicle]"
prediction_tagString:filter="prediction_tag:[key1_value1,key1_value2]"
prediction_scoreNumeric=, <, <=, >, >=filter="prediction_score>=0.95"
prediction_widthNumeric=, <, <=, >, >=filter="prediction_width=200"
prediction_heightNumeric=, <, <=, >, >=filter="prediction_height>150"
prediction_areaNumeric=, <, <=, >, >=filter="prediction_area<5000"
prediction_x_locationNumeric=, <, <=, >, >=filter="prediction_x_location<=400"
prediction_y_locationNumeric=, <, <=, >, >=filter="prediction_y_location>250"
bounding_box_match_iouNumeric=, <, <=, >, >=filter="bounding_box_match_iou>=0.7"
bounding_box_match_failureString=, :filter="bounding_box_match_failure:[true_positive,false_positive,mispredicted,false_negative]"
video_keyString=, :filter="video_key:[video123,video456]"
video_filenameString=, :filter="video_filename:[video1.mp4]"