Skip to main content

Combine or Negate

Group or separate items in your search


You can add together multiple search parameters to expand your search. You can even combine negated search terms for more advanced tasks.

In annotation search, Filter and Rank is a list of Annotation objects. Filtered annotations will be ANDed.

info

Before using the Python SDK, Node.js SDK, or any of our gRPC clients, ensure they are properly installed on your machine. Refer to their respective installation guides for instructions on how to install and initialize them.

OR Search Operation

The OR filter lets you expand your search to include results that match any of the specified conditions, rather than requiring all of them to be met.

# Import necessary modules
from clarifai.client.search import Search
from clarifai.client.user import User
from google.protobuf import struct_pb2
from PIL import Image
import requests
from IPython.display import display

# User-specific credentials
USER_ID = '' # User ID
APP_ID = '' # Application ID
PAT = '' # Personal Access Token

# Define dataset and image URL
CREATE_DATASET_ID = "ci_search_dataset"
DOG_IMG_URL = "https://samples.clarifai.com/dog.tiff"

# Create Clarifai application
app_obj = User(user_id=USER_ID, pat=PAT).create_app(app_id=APP_ID, base_workflow="General")

# Create a dataset
dataset_obj = app_obj.create_dataset(CREATE_DATASET_ID)

# Initialize inputs object
inp_obj = app_obj.inputs()

# Define metadata for the image
metadata = struct_pb2.Struct()
metadata.update({"Breed": "Saint Bernard"})

# Get input from URL and upload it
input_proto = inp_obj.get_input_from_url(
dataset_id=CREATE_DATASET_ID,
input_id="dog-tiff",
image_url=DOG_IMG_URL,
labels=["dog"],
geo_info=[-30.0, 40.0], # longitude, latitude
metadata=metadata)
inp_obj.upload_inputs([input_proto])

# Define OR filter
or_filter = [{ # OR
"concepts": [{
"name": "deer",
"value": 1
}, {
"name": "dog",
"value": 1
}]
}]

# Perform search with OR filter
search = app_obj.search()
res = search.query(ranks=[{"image_url": "https://samples.clarifai.com/dog.tiff"}], filters=or_filter)

# Process search results
resp = list(res)
for r in resp:
hit = r.hits[0].input.data.image.url
break

# Display the image
print(hit)
hit_img = Image.open(requests.get(hit, stream=True).raw).resize((300,250))
display(hit_img)

AND Search Operation

The AND operation enables you to refine search results by specifying multiple conditions that must all be satisfied at the same time.

For example, if a user searches for images containing both the concepts "dog" and "deer," only those images labeled with both concepts will be returned.

# Import necessary modules
from clarifai.client.search import Search
from clarifai.client.user import User
from google.protobuf import struct_pb2
from PIL import Image
import requests
from IPython.display import display

# Define user-specific credentials
USER_ID=''
APP_ID=''
PAT=''

# Define constants
CREATE_DATASET_ID = "ci_search_dataset"
DOG_IMG_URL = "https://samples.clarifai.com/dog.tiff"

# Create a new application
app_obj = User(user_id=USER_ID, pat=PAT).create_app(app_id=APP_ID, base_workflow="General")

# Create a new dataset
dataset_obj = app_obj.create_dataset(CREATE_DATASET_ID)

# Initialize Inputs object for uploading data
inp_obj = app_obj.inputs()

# Define metadata for the input
metadata = struct_pb2.Struct()
metadata.update({"Breed": "Saint Bernard"})

# Get input from URL and upload it to the dataset
input_proto = inp_obj.get_input_from_url(
dataset_id=CREATE_DATASET_ID,
input_id="dog-tiff",
image_url=DOG_IMG_URL,
labels=["dog"],
geo_info=[-30.0, 40.0], # longitude, latitude
metadata=metadata)
inp_obj.upload_inputs([input_proto])

# Define an AND filter
and_filter = [
{ # AND
"concepts": [{
"name": "dog",
"value": 1
}]
},
{
"concepts": [{
"name": "deer",
"value": 1
}]
}
]

# Create a search object
search = app_obj.search()

# Perform a search query with the specified rank and AND filter
res = search.query(ranks=[{"image_url": "https://samples.clarifai.com/dog.tiff"}], filters=and_filter)

# Convert search results to a list
resp = list(res)

# Print the length of the search results
print(len(resp)) # Should be zero

Combine Filter and Rank

When you combine both Filter and Rank, filter will be applied before ranking annotations. This is important because limiting the results set on large applications can speed up the overall query drastically when doing a ranking.

from clarifai.client.search import Search
from clarifai.client.input import Inputs
from PIL import Image
import requests
from IPython.display import display

# Define your Clarifai credentials
USER_ID = ''
APP_ID = ''
PAT = ''

# Initialize the Clarifai client with your credentials
client = User(user_id=USER_ID)

# Create an application within Clarifai with the specified ID and base workflow
# The 'Universal' workflow is a general-purpose workflow that can handle various types of data
app = client.create_app(app_id=APP_ID, base_workflow="Universal", pat=PAT)

# Initialize a search object for the specified user, application, and access token
s = Search(user_id=USER_ID, app_id=APP_ID, pat=PAT)

# Initialize an Inputs object for the specified user, application, and access token
inp_obj = Inputs(user_id=USER_ID, app_id=APP_ID, pat=PAT)

# Prepare an input protobuf message from the provided image URL
input_proto = inp_obj.get_input_from_url(
input_id="dog-tiff",
image_url="https://samples.clarifai.com/dog.tiff",
labels=["dog"],
geo_info=[-30.0, 40.0], # longitude, latitude
)

# Upload the prepared input protobuf message to the Clarifai application
inp_obj.upload_inputs([input_proto])

# Perform a search query with specified ranks and filters
response = s.query(ranks=[{"image_url": "https://samples.clarifai.com/dog.tiff"}], filters=[{"concepts": [{'name':'dog','value':1}]}])

# Process the response to extract the URL of the first matching image
resp = list(response)
for r in resp:
hit = r.hits[0].input.data.image.url
break

# Print the URL of the matched image
print(hit)

# Open the matched image URL, resize it, and display it
hit_img = Image.open(requests.get(hit, stream=True).raw).resize((300,250))
display(hit_img)

Combine Filter by Metadata and Rank

You can also search over custom metadata and easily rank the results.

################################################################################
# In this section, we set the user authentication, app ID, and concept ID.
# Change these strings to run your own example.
###############################################################################

USER_ID = "YOUR_USER_ID_HERE"
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = "YOUR_PAT_HERE"
APP_ID = "YOUR_APP_ID_HERE"
# Change this to rank the filtered results by your own concept
CONCEPT_ID = "cat"

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2
from google.protobuf.struct_pb2 import Struct

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (("authorization", "Key " + PAT),)

userDataObject = resources_pb2.UserAppIDSet(
user_id=USER_ID, app_id=APP_ID
) # The userDataObject is required when using a PAT

search_metadata = Struct()
search_metadata.update({"type": "animal"})

post_annotations_searches_response = stub.PostAnnotationsSearches(
service_pb2.PostAnnotationsSearchesRequest(
user_app_id=userDataObject,
searches=[
resources_pb2.Search(
query=resources_pb2.Query(
filters=[
resources_pb2.Filter(
annotation=resources_pb2.Annotation(
data=resources_pb2.Data(metadata=search_metadata)
)
)
],
ranks=[
resources_pb2.Rank(
annotation=resources_pb2.Annotation(
data=resources_pb2.Data(
concepts=[ # You can search by multiple concepts.
resources_pb2.Concept(
id=CONCEPT_ID, # You could search by concept Name as well.
value=1, # Value of 0 will search for images that don't have the concept.
)
]
)
)
)
],
)
)
],
pagination=service_pb2.Pagination(per_page=2, page=1),
),
metadata=metadata,
)

if post_annotations_searches_response.status.code != status_code_pb2.SUCCESS:
raise Exception("Post searches failed, status: " + post_annotations_searches_response.status.description)

print("Search result:")
for hit in post_annotations_searches_response.hits:
print("\tScore %.2f for annotation: %s off input: %s" % (hit.score, hit.annotation.id, hit.input.id))

Negate Search Criteria

You can find all the data that is NOT similar to a given criteria.

################################################################################
# In this section, we set the user authentication, app ID, and the concept we
# we want to search by. Change these strings to run your own example.
################################################################################

USER_ID = 'YOUR_USER_ID_HERE'
# Your PAT (Personal Access Token) can be found in the Account's Security section
PAT = 'YOUR_PAT_HERE'
APP_ID = 'YOUR_APP_ID_HERE'
# Change this to search by your own concept
CONCEPT_NAME = 'cat'

##########################################################################
# YOU DO NOT NEED TO CHANGE ANYTHING BELOW THIS LINE TO RUN THIS EXAMPLE
##########################################################################

from clarifai_grpc.channel.clarifai_channel import ClarifaiChannel
from clarifai_grpc.grpc.api import resources_pb2, service_pb2, service_pb2_grpc
from clarifai_grpc.grpc.api.status import status_code_pb2

channel = ClarifaiChannel.get_grpc_channel()
stub = service_pb2_grpc.V2Stub(channel)

metadata = (('authorization', 'Key ' + PAT),)

userDataObject = resources_pb2.UserAppIDSet(user_id=USER_ID, app_id=APP_ID) # The userDataObject is required when using a PAT

post_annotations_searches_response = stub.PostAnnotationsSearches(
service_pb2.PostAnnotationsSearchesRequest(
user_app_id=userDataObject,
searches = [
resources_pb2.Search(
query=resources_pb2.Query(
filters=[
resources_pb2.Filter(
annotation=resources_pb2.Annotation(
data=resources_pb2.Data(
concepts=[ # You can search by multiple concepts
resources_pb2.Concept(
name=CONCEPT_NAME, # You could search by concept id as well
)
]
)
),
negate=True
)
]
)
)
]
),
metadata=metadata
)

if post_annotations_searches_response.status.code != status_code_pb2.SUCCESS:
print(post_annotations_searches_response.status)
raise Exception("Post searches failed, status: " + post_annotations_searches_response.status.description)

print("Search result:")
for hit in post_annotations_searches_response.hits:
print("\tScore %.2f for annotation: %s off input: %s" % (hit.score, hit.annotation.id, hit.input.id))

Find Duplicate Images in Dataset

Here's how you can use the PostInputsSearches endpoint to identify near-duplicate images within a given dataset.

You can also use the min_value threshold parameter to refine the search results, ensuring that only images surpassing a specified minimum probability resemblance score are included in the output. .

curl -X POST "https://api.clarifai.com/v2/users/YOUR_USER_ID_HERE/apps/YOUR_APP_ID_HERE/inputs/searches" \
-H "Authorization: Key YOUR_PAT_HERE" \
-H "Content-Type: application/json" \
-d '{
"searches": [
{
"query": {
"filters": [
{
"input": {
"dataset_ids": ["YOUR_DATASET_ID_HERE"]
}
}
],
"ranks": [
{
"annotation": {
"data": {
"image": {
"url": "https://samples.clarifai.com/metro-north.jpg"
}
}
}
}
]
},
"min_value": 0.95
}
]
}'