Search

The search functionality provides extensive options for retrieving resources and is available on a limited set of API calls, including:

The search interface utilizes Solr, enabling most of its functions to be available for use.

This includes a wide variety of query parameters that allow you to customize your search and filter results based on various criteria. Some of the most common Solr query parameters are:

  • q: The query parameter is used to perform a full-text search on a set of documents. This parameter is required for all search requests.

  • fq: The filter query parameter allows you to specify a filter that can be used to restrict the set of documents returned by a search. Multiple filter queries can be combined to further narrow down the results.

  • sort: The sort parameter is used to specify the sort order of the results. You can specify one or more fields to sort on, as well as the direction of the sort (ascending or descending).

  • offset: The offset parameter is used to specify the offset of the first document to be returned in the result set. This is useful for pagination.

  • limit: The limit parameter is used to specify the maximum number of documents to be returned in the result set. This is useful for pagination as well.

  • fl: The field list parameter is used to specify which fields should be returned in the search results. You can specify one or more fields to be returned, separated by commas.

For a more comprehensive list of Solr query parameters and their descriptions, please see the official Solr documentation at https://solr.apache.org/guide/7_2/common-query-parameters.html.

Documents

The items returned by the API are Solr documents, which may not fully represent the resource being listed.

For instance, an annotation may appear like this:

{
  "annotationProductionId": 16846,
  "circled": false,
  "created": 1639744310617,
  "createdBy": "REST",
  "creatorId": 2,
  "crossProduction": true,
  "end": 1,
  "funnel": "MediaObjectAnnotation",
  "hasScreenshot": false,
  "id": 5384922,
  "keyframeFrames": -1,
  "language": "xx",
  "lastUpdated": 1639744324144,
  "loggingStatus": "NOT_STARTED",
  "mediaObjectId": 1563093,
  "modifiedBy": "user:2",
  "nonPreferred": false,
  "objectType": "MediaObjectAnnotation",
  "productionId": 16846,
  "rating": 0.0,
  "start": 0,
  "subtitlingStatus": "NOT_STARTED",
  "transcriptionStatus": "NOT_STARTED",
  "version": 1
}

However, the corresponding search call document would look more like this:

{
  "id": "Annotation_5384922",
  "type": "TECHNICAL_DETAILS",
  "lastUpdated": 1639744324144,
  "created": 1639744310617,
  "objectId": 5384922,
  "objectType": "MediaObjectAnnotation",
  "createdBy": "REST",
  "version": 1,
  "creatorId": 2,
  "annotation_type": "MediaObjectAnnotation",
  "start": 0,
  "end": 1,
  "funnel": "MediaObjectAnnotation",
  "annotation_productionId": 16846,
  "mediaObjectId": 1563093,
  "rating": 0.0,
  "language": "xx",
  "threadGroupId": 5384922,
  "mediaObjectIsDeleted": false,
  "packageGroup": 1563093,
  "productionId": 16846,
  "mediaObjectCreator": 2,
  "mediaObjectCreated": 1639744310509,
  "mediaObjectType": "IMAGE",
  "lc_mediaObjectType": "IMAGE",
  "autocomplete": [
    "giphy.gif!!!THIS_IS_MY_DELIMITER!!!mediaObjectName",
    "RAW;undefined;HIGH!!!THIS_IS_MY_DELIMITER!!!moiTypes",
    "IMAGE!!!THIS_IS_MY_DELIMITER!!!mediaObjectType",
    "giphy!!!THIS_IS_MY_DELIMITER!!!technical_s_reelName",
    "250x172!!!THIS_IS_MY_DELIMITER!!!technical_s_resolution",
    "IMAGE!!!THIS_IS_MY_DELIMITER!!!mediaObjectType",
    "PROXY;web;ULTRA!!!THIS_IS_MY_DELIMITER!!!moiTypes"
  ],
  "lc_autocomplete": [
    "giphy.gif!!!THIS_IS_MY_DELIMITER!!!mediaObjectName",
    "raw;undefined;high!!!THIS_IS_MY_DELIMITER!!!moiTypes",
    "image!!!THIS_IS_MY_DELIMITER!!!mediaObjectType",
    "giphy!!!THIS_IS_MY_DELIMITER!!!technical_s_reelName",
    "250x172!!!THIS_IS_MY_DELIMITER!!!technical_s_resolution",
    "image!!!THIS_IS_MY_DELIMITER!!!mediaObjectType",
    "proxy;web;ultra!!!THIS_IS_MY_DELIMITER!!!moiTypes"
  ],
  "mediaObjectCreatedBy": "120da17d-387a-4014-8908-2841b91db3e2",
  "samplerate_denum": 1,
  "samplerate_num": 20,
  "samplerate_drop_frame": false,
  "samplerate_human": "20.00",
  "mediaObjectName": "giphy.gif",
  "lc_mediaObjectName": "giphy.gif",
  "growing": false,
  "mediaObjectAnnotationId": 5384922,
  "global_rating": 0.0,
  "hasScreenshot": false
}

The indexed document may omit certain properties and at the same time add additional properties on which can be searched.

This concept is elaborated more on in Annotations in the SOLR search index.

Facets example

It is possible to use the Solr Facet API parameters to request a list of field values for documents matching the search query.

facet
Limecraft Flow interface for listing facet values for the mediaObjectType field

For example, to request the available values of the mediaObjectType field, you could use the following parameters:

Parameter Description

rows=0

We want no results

q=*

fq=…​

Use q and fq as you normally would

facet=true

Enable faceting

facet.field=mediaObjectType

Return all facet values for the mediaObjectType field

f.mediaObjectType.facet.offset=0

f.mediaObjectType.facet.limit=50

Pagination. Return at most 50 facet values, starting at the first one.

f.mediaObjectType.facet.mincount=1

Only return a facet value if at least 1 search result has this value

f.mediaObjectType.facet.sort=count

Sort facet values by count (the one with the most search results comes first). Alternative is by index (alphabetically).

f.mediaObjectType.facet.exists=true

By default, the facet response will contain a detailed count of how many search results match a certain value. If this is not needed, set facet.exists to true, which will not return counts (cap the counts to 1). This is faster.

f.mediaObjectType.facet.missing=true

Also return an entry representing clips not having the field set.

The response of this call would be

{
    results: [], // because rows=0
	facetFields: [
		{
			name: “mediaObjectType”,
			valueCount: 6,
			values: {
				// the right-hand side is the count of search
				// results matching this facet value. Because
				// facet.exists=true was passed, this is
				// capped to 1, instead of returning the
				// actual count.
				AUDIO: 1,
				VIDEO: 1,
				DOCUMENT: 1,
				IMAGE: 1,
				missing: 0
			}
		},
		// … other facet fields (if requested more)
	]
}

Grouping example

It is possible to group search results together. For example, say we are searching for clips that have an annotation with the tag "bunny".

If we would simply search with a filter query fq=funnel:MediaObjectAnnotation, we would only find matches where the "bunny" tag is actually on the MediaObjectAnnotation. Clips with a ReviewComment annotation with a "bunny" tag would not show up in the search results.

To solve this problem, we have to search all annotations, but group the results by MediaObject. The grouping is based on Solr grouping, more info here.

Parameter Description

q=*

Query all annotations, we’ll use fq to add field-level criteria.

start=0

rows=25

Pagination

sort=created DESC

Sort by created date, in descending order

group=true

Enable grouping

group.field=mediaObjectId_s_nm_d

Group by the id of the MediaObject (so all annotations of the same clip will be in the same group)

group.limit=3

Return at most 3 results per group (per clip)

group.main=false

Do not ‘flatten’ the results. If flattened, the same structure as regular results is used, but information on the grouping is lost.

group.ngroups=false

Do not return a count of groups that have matched the query. When true, the call is a lot slower.

isCompressed=true

Only available on annotation search endpoints.

Optionally add this to put MediaObject-level fields in a separate mediaObjectProperties key. This makes the response less verbose, as those properties are only returned once per group now, instead of duplicated on each annotation within a group.

The response format of this call has another structure than the ‘regular’ search results (see below). The grouped results are in groupResponse.values[0], which is an array of objects with a groupValue (the value of the group.field field for this group, so, the MediaObject id) and a result array. The result array contains the individual results, and is similar to the regular search results of the previous section.

When isCompressed=true was set, common fields of the group (so fields of the MediaObject, which would be the same for any result in the same group) are returned on the mediaObjectProperties key.

{
	groupResponse: {
		values: [
			{
				matches: 5,
				name: “mediaObjectId_s_nm_d”,
				values: [
					{
						groupValue: “470787”,
						result: [
							// array of results similar to ‘regular’ search endpoint
						]
					},
					{
						groupValue: “51058”,
						result: [
							// array of results similar to ‘regular’ search endpoint
						]
					},
				]
			}
		]
	},
	// only if isCompressed is true
	mediaObjectProperties: {
		470787: {
			mediaObjectName: “Big Buck Bunny.mp4”,
			…
		},
		51058: {
			mediaObjectName: “MyMovie.mxf”,
			…
		}
	}
}