Filtering Results using Metadata Filters
Overview
The metadataFilter
of the advancedSearch
allows you to filter search results flexibly by providing a MongoDB-style query structure.
It replaces the older pre-defined static metadata fields, offering a more powerful and expressive way to search through your music data.
The metadataFilter
follows a JSON format and supports logical operations like $and
, $or
, $in
, $gt
, and others.
A detailed guide for the Advanced Search and how you can use it can be found (here).
Syntax and Format
The metadataFilter
field expects a JSON object using MongoDB-like operators.
A single metadata filter can look like this. Each field name corresponds to metadata or tagging of a track.
{ "<fieldName>": { "<operator>": "<value>" } }
Metadata Filter Fields
Field Name | Type | Operators | Values |
---|---|---|---|
arousal | Number | $gt , $gte , $lt , $lte , $eq , $ne , $exists | AudioAnalysisV7Result.arousal |
valence | Number | $gt , $gte , $lt , $lte , $eq , $ne , $exists | AudioAnalysisV7Result.valence |
bpmPrediction | Number | $gt , $gte , $lt , $lte , $eq , $ne , $exists | Integer for bpm. |
bpmRangeAdjusted | Number | $gt , $gte , $lt , $lte , $eq , $ne , $exists | Integer between 60-180 bpm. |
genreTags | Array | $in , $nin , $exists | AudioAnalysisV6GenreTags |
moodTags | Array | $in , $nin , $exists | AudioAnalysisV6MoodTags |
subgenreTags | Array | $in , $nin , $exists | AudioAnalysisV6SubgenreTags |
moodAdvancedTags | Array | $in , $nin , $exists | AudioAnalysisV6MoodAdvancedTags |
characterTags | Array | $in , $nin , $exists | AudioAnalysisV6CharacterTags |
movementTags | Array | $in , $nin , $exists | AudioAnalysisV6MovementTags |
advancedGenreTags | Array | $in , $nin , $exists | AudioAnalysisV7GenreTags |
advancedSubgenreTags | Array | $in , $nin , $exists | AudioAnalysisV7SubgenreTags |
keyPrediction | Array | $in , $nin , $exists | MusicalKey |
instrumentTags | Array | $in , $nin , $exists | AudioAnalysisV6InstrumentTags |
advancedInstrumentTagsExtended | Array | $in , $nin , $exists | AudioAnalysisV7ExtendedInstrumentTags |
voiceTags | Array | $in , $nin , $exists | AudioAnalysisV6VoiceTags |
voicePresenceProfile | Array | $in , $nin , $exists | AudioAnalysisV6VoicePresenceProfile |
predominantVoiceGender | Array | $in , $nin , $exists | AudioAnalysisV6PredominantVoiceGender |
freeGenreTags | Array | $in , $nin , $exists | List of free genre tags. |
musicalEraTag | Array | $in , $nin , $exists | List of musical era tags. |
customTags | Array | $in , $nin , $exists | LibraryTrack.customTags |
Metadata Filter Operators
Operator | Description | Format |
---|---|---|
$and | Combine a list of filters where all must match. | {"$and": [filter1, filter2, ...]} |
$or | Combine a list of filters where at least one must match. | {"$or": [filter1, filter2, ...]} |
$eq | Condition for results to exactly match a value. | {"$eq": int/float/str/bool } |
$ne | Condition for results to not match a value. | {"$ne": int/float/str/bool } |
$gt | Condition for results to be greater than a value. | {"$gt": int/float } |
$gte | Condition for results to be greater than or equal to a value. | {"$gte": int/float } |
$lt | Condition for results to be less than a value. | {"$lt": int/float } |
$lte | Condition for equal for results to be less than or equal to a value. | {"$lte": int/float } |
$in | Condition for results to match any value in a list. | {"$in": [int/float/str, ...]} |
$nin | Condition for results to not match any value in a list. | {"$nin": [int/float/str, ...]} |
$exists | Condition for results to include or exclude a field. | {"$exists": true/false} |
Examples
1. Simple Numeric Filter
Filter tracks where valence > 0.5
.
(See Syntax and Format for other numeric metadata filter fields)
{ "valence": {"$gt": 0.5} } }
GraphiQL
Example query with metadata filters for the new advancedSearch
endpoint:
Curl
Example curl request with metadata filters for the new advancedSearch
endpoint:
curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": { "valence": { "$gt": 0.5 } } } }'
2. Filter by Tags
Find tracks where specific tags are given or exluded. (See Syntax and Format for other metadata filter tags/array fields.)
{ "genreTags": { "$in": ["rock"] } }
GraphiQL
Example query with metadata filters for the new advancedSearch
endpoint:
Curl
Example curl request with metadata filters for the new advancedSearch
endpoint:
curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": { "genreTags": { "$in": ["rock"] } } } }'
3. Combining Multiple Conditions
Find tracks where:
valence > 0.5
- AND (
genreTags
contains "rock" and "pop" ORmoodTags
contains "energetic")
(See Syntax and Format for other available metadata filters)
{
"$and": [
{ "valence": { "$gt": 0.5 } },
{
"$or": [
{ "genreTags": { "$in": ["rock", "pop"] } },
{ "moodTags": { "$in": ["energetic"] } }
]
}
]
}
GraphiQL
Example query with metadata filters for the new advancedSearch
endpoint:
Curl
Example curl request with metadata filters for the new advancedSearch
endpoint:
curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": {"$and": [{"valence": {"$gt": 0.5}}, {"$or": [{"genreTags": {"$in": ["rock", "pop"]}}, {"moodTags": {"$in": ["energetic"]}}]}]}}}'
Validation Rules
- The structure must be valid JSON.
- Only supported operators are allowed (See Syntax and Format - Metadata Filter Opterators).
- Field names must match the available metadata fields (See Syntax and Format - Metadata Filter Fields).
If your metadataFilter
is invalid, the API will return an error indicating what was wrong with your query.
Possible Errors when Using metadataFilter
If your metadataFilter
is incorrectly structured or uses unsupported fields or operators, the advanced search endpoint will return an AdvancedSearchError with an error code invalidMetadataFilter.
This error is raised during server-side validation and provides helpful information to correct your query.
Error Scenarios
Error Scenario | Cause | Example | Error Message |
---|---|---|---|
Invalid Top-Level Key | Using a field name that is not a known metadata field or a logical operator ($and , $or ). | { "unknownField": { "$eq": "value" } } | Invalid metadata filter error for unknownField: Expected a valid top level metadata field: '$and', '$or' or any of [...] |
Unsupported Logical Operator | Using an unrecognized operator. | { "valence": { "$contains": "value" } } | Invalid metadata filter error for $contains: Expected one of ['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin', '$exists', '$and', '$or']. |
Malformed Logical Group | $and or $or provided with a non-list or invalid structure. | { "$and": "invalidType" } | Invalid metadata filter error for $and: Got value invalidType (type str). Expected a list or subquery dictionaries |
Invalid Field Condition | Providing a raw value instead of a condition dictionary for a metadata field. | { "valence": 0.8 } | Invalid metadata filter error for valence: Expected one of ['$eq', '$ne', '$gt', '$gte', '$lt','$lte', '$in', '$nin', '$exists', '$and', '$or']. |
Validation Error in Operator | Using wrong data types inside operator filters. | { "valence": { "$in": 5 } } | Operator '$in' expects a list of values, but received an integer. |
Unknown Metadata Field | Typo or unsupported metadata field. | { "vallence": { "$gt": 0.5 } } | Invalid metadata filter error for vallence: Expected a valid top level metadata field: '$and', '$or' or any of [...] |
Best Practices to Avoid Errors
- Double-check your field names against the available metadata fields.
- Ensure logical groups (
$and
,$or
) contain lists or valid subqueries. - Ensure to only use supported MongoDB-style operators (
$eq
,$in
,$gt
, etc.). - Always provide filtering conditions inside
{}
brackets under fields. - Validate your JSON format before sending queries.