Grouping and ungrouping
Grouping and ungrouping refer to the process of organizing the results of a search query in a specific way. The platform allows for grouping based on the unique identifiers of the videos. For example, this is useful when building a user interface, because it allows your users to better understand and navigate the search results. On the other hand, ungrouping presents your search results in a flat list. This is useful if you want to view all of the search results in a simple manner. Note that this feature can only be used with simple queries.
To group or ungroup items in a response, use the group_by
parameter, specifying one of the following values:
video
: The platform will group the matching video clips in the response by video.clip
: The matching video clips in the response will not be grouped.
Note
The
group_by
parameter is optional and its default value isclip
. If omitted, the platform will use the default value. For clarity, the examples in this section always specify thegroup_by
parameter.
For a description of each field in the request and response, see the API Reference> Make a search request page.
You can interact with the platform using one of the available SDKs or an HTTP client like requests or axios. Follow the steps in one of the sections below, depending on your use case.
Prerequisites
- You're familiar with the concepts that are described on the Platform overview page.
- You've already created an index, and the Marengo video understanding engine is enabled for this index.
- You've already uploaded a video, and the platform has finished indexing it.
Use an SDK
Refer to this section if you use one of the available SDKs.
Grouping items in a response
The following example code groups the matching video clips in the response by video:
from twelvelabs import TwelveLabs
client = TwelveLabs(api_key="<YOUR_API_KEY>")
search_results = client.search.query(
index_id="<YOUR_INDEX_ID>,
query="<YOUR_QUERY>,
options=["visual"],
group_by="video"
)
# Utility function to print a specific page
def print_page(page):
for video in page:
print(f"Video id: {video.id}")
for clip in video.clips:
print(clip)
print(
f"\tscore={clip.score} start={clip.start} end={clip.end} confidence={clip.confidence} metadata={clip.metadata}"
)
print_page(search_results.data)
while True:
try:
print_page(next(search_results))
except StopIteration:
break
import { TwelveLabs, GroupByVideoSearchData } from 'twelvelabs-js';
const client = new TwelveLabs({ apiKey: '<YOUR_API_KEY>'});
let searchResults = await client.search.query({
indexId: '<YOUR_INDEX_ID>'
query: '<YOUR_QUERY>',
options: ['visual'],
groupBy: 'video',
});
printPage(searchResults);
while (true) {
const page = await searchResults.next();
if (page === null) break;
else printPage(page);
}
// Utility function to print a specific page
function printPage(searchData) {
(searchData.data as GroupByVideoSearchData[]).forEach((video) => {
console.log(`videoId=${video.id}`);
video.clips?.forEach((clip) => {
console.log(
` score=${clip.score} start=${clip.start} end=${clip.end} confidence=${clip.confidence}`,
);
});
});
}
The output should look similar to the following one:
Video id: 65d60bcf48db9fa780cb415e
score=83.73 start=273.96875 end=289.0625 video_id='65d60bcf48db9fa780cb415e' metadata=[{'type': 'visual'}] confidence='high'
score=83.73 start=273.96875 end=289.0625 confidence=high metadata=[{'type': 'visual'}]
score=83.55 start=397.921875 end=439.84375 video_id='65d60bcf48db9fa780cb415e' metadata=[{'type': 'visual'}] confidence='high'
score=83.55 start=397.921875 end=439.84375 confidence=high metadata=[{'type': 'visual'}]
score=83.46 start=294.5625 end=311.84375 video_id='65d60bcf48db9fa780cb415e' metadata=[{'type': 'visual'}] confidence='high'
Video id: 65d5fbad48db9fa780cb415c
score=83.36 start=342.6875 end=353.140625 video_id='65d5fbad48db9fa780cb415c' metadata=[{'type': 'visual'}] confidence='high' thumbnail_url=None module_confidence=None
score=83.36 start=342.6875 end=353.140625 confidence=high metadata=[{'type': 'visual'}]
score=83.32 start=164.671875 end=200.71875 video_id='65d5fbad48db9fa780cb415c' metadata=[{'type': 'visual'}] confidence='high' thumbnail_url=None module_confidence=None
score=83.32 start=164.671875 end=200.71875 confidence=high metadata=[{'type': 'visual'}]
score=83.31 start=329.96875 end=337.75 video_id='65d5fbad48db9fa780cb415c' metadata=[{'type': 'visual'}] confidence='high' thumbnail_url=None module_confidence=None
score=83.31 start=329.96875 end=337.75 confidence=high metadata=[{'type': 'visual'}]
In this example, note that the data
array contains a list of objects. Each object corresponds to a video that matches your query and is composed of the following key-value pairs:
clips
: An array that groups the information about all the matching video clips in that video.id
: The unique identifier of the video that matched your query.
Ungrouping items in a response
The following example performs a search request, and the matching video clips in the response are not grouped:
from twelvelabs import TwelveLabs
client = TwelveLabs(api_key="<YOUR_API_KEY>")
search_results = client.search.query(
index_id="<YOUR_INDEX_ID>",
query= "<YOUR_QUERY>"
options=["visual"],
group_by='clip'
)
# Utility function to print a specific page
def print_page(page):
for clip in page:
print(
f" video_id={clip.video_id} score={clip.score} start={clip.start} end={clip.end} confidence={clip.confidence} metadata={clip.metadata}"
)
print_page(search_results.data)
while True:
try:
print_page(next(search_results))
except StopIteration:
break
import { TwelveLabs, SearchData } from 'twelvelabs-js';
const client = new TwelveLabs({ apiKey: '<YOUR_API_KEY>'});
let searchResults = await client.search.query({
indexId: '<YOUR_INDEX_ID>'
query: '<YOUR_QUERY>',
options: ['visual'],
group_by='clip',
});
printPage(searchResults.data);
while (true) {
const page = await searchResults.next();
if (page === null) break;
else printPage(page);
}
// Utility function to print a specific page
function printPage(searchData) {
(searchData as SearchData[]).forEach((clip) => {
console.log(
`video_id= ${clip.videoId} score=${clip.score} start=${clip.start} end=${clip.end} confidence=${clip.confidence} metadata=${JSON.stringify(clip.metadata)}`,
);
});
}
The output should look similar to the following one:
video_id=65d6131c48db9fa780cb415f score=52.04 start=4.5625 end=14.8125 confidence=low metadata=[{'type': 'visual'}]
video_id=65d6131c48db9fa780cb415f score=50.94 start=20.9375 end=25.09375 confidence=low metadata=[{'type': 'visual'}]
video_id=65d60bcf48db9fa780cb415e score=50.94 start=20.9375 end=25.09375 confidence=low metadata=[{'type': 'visual'}]
Use an HTTP client
Refer to this section if you use clients such as requests
or axios
.
Grouping items in a response
The following example code searches for car accidents, and the matching video clips in the response are grouped by video:
SEARCH_URL = f”{API_URL}/search”
data = {
“query”: “car accidents”,
“index_id”: INDEX_ID,
“search_options”: [“visual”],
“group_by”: “video”
}
response = requests.post(SEARCH_URL, headers=headers, json=data)
print (f’Status code: {response.status_code}’)
pprint(response.json())
const SEARCH_URL = `${API_URL}/search`
const data = {
'query': 'bear chasing a man',
'index_id': INDEX_ID,
'search_options': ['visual'],
'group_by': 'video'
}
const resp = await axios.post(
SEARCH_URL,
data,
{
'headers': {
'x-api-key': API_KEY
}
}
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))
The following output has been truncated for brevity:
Status code: 200
{
"search_pool": {
"total_count": 13,
"total_duration": 8731,
"index_id": "639961c9e219c90227c371a2"
},
"data": [
{
"clips": [
{
"score": 86.69,
"start": 137.1875,
"end": 149.1875,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996260ce36463e0199c8c5",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/138.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T121123Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=77fbecb5fea214120d86e89c144660b20414f0957970621bf299e3d0e261ebec"
},
{
"score": 86.17,
"start": 173.1875,
"end": 193.5625,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996260ce36463e0199c8c5",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T121123Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=4c2049b56aaa3e1b0aec958fbdce359cd89390830b370cb54f926e77b51c04a2"
}
],
"id": "63996260ce36463e0199c8c5"
},
{
"clips": [
{
"score": 86.14,
"start": 624.46875,
"end": 630.46875,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996246ce36463e0199c8c4",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996246ce36463e0199c8c4/625.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T121123Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=8d7d1014ed115ca6b8e76a488662e00afb5d5aad581f8701d0f82785c14c0e56"
},
{
"score": 85.37,
"start": 432.46875,
"end": 442.46875,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996246ce36463e0199c8c4",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996246ce36463e0199c8c4/433.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T121123Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=755fb037c4f6be94583ff261282e35d11b6d0db6af8a6de7bcfc00a63a013bb4"
}
],
"id": "63996246ce36463e0199c8c4"
}
],
"page_info": {
"limit_per_page": 10,
"total_results": 4,
"total_inner_matches": 32,
"page_expired_at": "2022-12-29T12:11:23Z"
}
}
In the example output above, note that the data
array contains a list of objects. Each object corresponds to a video that matches your query and is composed of the following key-value pairs:
clips
: An array that groups the information about all the matching video clips in that video.id
: The unique identifier of the video that matched your query.
Ungrouping items in a response
The following example code searches for car accidents, and the matching video clips in the response are not grouped:
SEARCH_URL = f”{API_URL}/search”
data = {
“query”: “car accidents”,
“index_id”: INDEX_ID,
“search_options”: [“visual”],
“group_by”: “clip”
}
response = requests.post(SEARCH_URL, headers=headers, json=data)
print (f’Status code: {response.status_code}’)
pprint(response.json())
const SEARCH_URL = `${API_URL}/search`
const data = {
'query': 'bear chasing a man',
'index_id': INDEX_ID,
'search_options': ['visual'],
'group_by': 'clip'
}
const resp = await axios.post(
SEARCH_URL,
data,
{
'headers': {
'x-api-key': API_KEY
}
}
)
const { data: response } = resp;
console.log(`Status code: ${resp.status}`)
console.log(JSON.stringify(response,null,4))
The following output was truncated for brevity:
Status code: 200
{
"search_pool": {
"total_count": 13,
"total_duration": 8731,
"index_id": "639961c9e219c90227c371a2"
},
"data": [
{
"score": 86.69,
"start": 137.1875,
"end": 149.1875,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996260ce36463e0199c8c5",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996260ce36463e0199c8c5/138.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T075204Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=1464a7f7516b5c42669135f7822e1f762f25036c0bb9b1382b40cc7de09188eb"
},
{
"score": 85.4,
"start": 483.6,
"end": 498.20625,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996232ce36463e0199c8c3",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996232ce36463e0199c8c3/484.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T075204Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=0b7564985d556b65da677719cfedb0fcbf2d8c8fada6af2bc289f6e526d3150d"
},
{
"score": 85.37,
"start": 432.46875,
"end": 442.46875,
"metadata": [
{
"type": "visual"
}
],
"video_id": "63996246ce36463e0199c8c4",
"confidence": "high",
"thumbnail_url": "https://project-one-thumbnail.s3.us-west-2.amazonaws.com/63996246ce36463e0199c8c4/433.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYRWJPOVHXE5SJ77T%2F20221229%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221229T075204Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=d7eae8609413622fe7d2afdd85d40637e9ab0b903a8f7b20d8f85252c5ef5a1d"
}
],
"page_info": {
"limit_per_page": 10,
"total_results": 222,
"page_expired_at": "2022-12-29T07:52:04Z",
"next_page_token": "52a2c8dc-8ff0-40c6-9a4e-8c2ce56212b3-1"
}
}
In the example output above, note that the data
array contains a list of objects, and each object has a property named video_id
, which represents the unique identifier of the video that matched your query.
Updated about 1 month ago