Filtering¶
Filter parameters allow for precise matching on fields in object records, only returning the object records exactly matching the identifier(s) you specify on a single field (or a group of fields). These fields are vocabulary controlled, that is, instead of typing in the word you want to find (e.g. “William Morris”), we use an identifier instead, such as “A8676”, or “THES12345”) which helps avoid issues with variations in spelling. Whilst this way of finding records is always to be preferred, it does mean you need to know the right identifier to use.
Filtering vs Constrained Search vs Full Search¶
Let’s compare the results from filtering, a general text search and a constrained (i.e. one field only) text search, all looking for the material ‘Jet’
General text search¶
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?q=Jet')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that mention the term 'Jet' anywhere in the record")
There are 543 objects that mention the term 'Jet' anywhere in the record
Constrained text search¶
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?q_material_technique=Jet')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that mention the term 'Jet' within materials and techniques fields")
There are 197 objects that mention the term 'Jet' within materials and techniques fields
Filter¶
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=AAT45514')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that have been catalogued as using the material 'Jet' (AAT45514)")
There are 51 objects that have been catalogued as using the material 'Jet' (AAT45514)
As we can see from the results, there are many more records using the term ‘Jet’ anywhere within the record than are found by searching specifically on the field for material or technique or filtering on the relevant identifier. This could be for a few different reasons:
Some of the matches on the general search for the term ‘Jet’ are using it with other meanings, such as Jet Engine, Design for Jet Jewellery. These might be irrelevant to your search for objects made of Jet (although perhaps the designs might also be of interest)
Some objects which are made of Jet have object records that have not been extensively catalogued, but they do mention in another text field the object is made of Jet. These objects would be excluded from your search if only on the material and technique field, or if filtering on the identifer for Jet (AAT45514)
Some objects could be made from a specific sub-type of Jet (if this exists). These would not be found by filtering on Jet (AAT45514), as the identifier used would not match. For this to work (which is a planned future enhancement to the API), we would need some form of hierarchical filtering to enable matching on a type (Jet) and all its sub-types.
So, in summary, while filtering on the identifier (the last query we ran) will provide the most precise results, it is more than likely to not recall all relevant results. Keep this in mind when you use filtering, that although the number returned gives the appearance of an exact count (e.g. the V&A holds a certain number of objects made of Jet), you should also compare this result with the other searches (using ‘q’ and ‘q_material_techniques’), to see if there are other objects not yet catalogued as extensively that would also match. As cataloguing is a never ending endeavour, these number are always likely to change over time.
Common Filter Operations¶
Finding the identifer you need to use¶
Certainly the most obvious question, how to find the right identifier to filter on. Beyond having memorised all the vocabularies there is no exact science to this. We have listed some common Identifiers to get you started, but after that a good approach is to run a text search and from the returned relevant object records look for the identifiers you need. For example if you want to filter on objects made in Manchester, do a general text search (or a constrained search on ‘q_place’) on ‘Manchester’ and look through the returned object records for the place identifier for Manchester, then query again but this time filtering on that identifier (it’s x28993 in case you wondered).
Matching on multiple filters of the same facet¶
You might want to filter on object records that contain for example, both silver and lace. This can be done by repeating the filter parameter:
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=AAT11029&id_material=AAT132861')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that contain silver ('AAT11029') and/or lace ('AAT132861')")
There are 9823 objects that contain silver ('AAT11029') and/or lace ('AAT132861')
Narrow Matching¶
(Multiple filters of the same facet)¶
As you might notice from the above result, the object records returned will be those that say the object is made with silver and lace, but it will also include those that only say the object was made with lace (with no mention of silver) and likewise for those object made with silver (with no mention of lace)
You might instead want to filter on object records that contain only both silver and lace. This is done as above, but you also need to set the search_mode parameter to “narrow” (otherwise known as boolean AND) instead of the default mode of “broad” (otherwise known as boolean OR).
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=AAT11029&id_material=AAT132861&search_mode=narrow')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that contain silver ('AAT11029') and lace ('AAT132861')")
There are 5 objects that contain silver ('AAT11029') and lace ('AAT132861')
Please note that this search mode setting then applies to all facets specified, if you are querying more than one. You cannot set only some facets search mode to broad/narrow.
Negation¶
You can also use filters to exclude any object records that would match the term(s) you have specified, by putting ‘-‘ before the identifier. So for example, if you want all object records that are not made of plastic:
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=-AAT14570&id_material=AAT10797')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that do not contain plastic ('AAT14570') and do contain glass ('AAT10797')")
There are 6753 objects that do not contain plastic ('AAT14570') and do contain glass ('AAT10797')
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=AAT14570&id_material=AAT10797')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that do contain plastic ('AAT14570') and do contain glass ('AAT10797')")
There are 11857 objects that do contain plastic ('AAT14570') and do contain glass ('AAT10797')
Note
Please note, use of negation automatically enables a narrow search mode (see Narrow Matching), as we do not think there is a use case for both negation and broad searching. If you do have one, please let us know.
Filter Operations¶
Filter by material¶
As covered already in the first example above, this lets you find object records cataloging some material as part of the object.
Identifiers in use come from the Getty Art & Architecture Thesaurus (identifiers prefixed with AAT), and identifiers from the V&A (identifiers prefixed with THES)
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_material=AAT10797')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that have been catalogued as using the material 'Glass' (AAT10797)")
There are 6823 objects that have been catalogued as using the material 'Glass' (AAT10797)
Filter by technique¶
Very similiar to materials, this filter lets you find catalogued object records making use of a particular production technique.
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_technique=AAT53241')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that use production technique 'etching' (AAT300053241)")
There are 32804 objects that use production technique 'etching' (AAT300053241)
Filter by style¶
This lets you filter object records by the artistic style of the object
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_style=AAT21515')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that use style 'vorticism' (AAT21515) as an artistic classification")
There are 20 objects that use style 'vorticism' (AAT21515) as an artistic classification
Filter by organisation¶
This lets you filter object records by the organisation connected in some way to an object
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_organisation=AUTH339709')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that were production by the Underground London Electric Railway Company organisation (AUTH339709)")
There are 38 objects that were production by the Underground London Electric Railway Company organisation (AUTH339709)
Filter by person¶
This letd you filter object records by the person connected in someway to an object
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_person=A6630')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print("There are {record_count} objects that are connected in some way to J.B. Yeats (A6630)")
There are {record_count} objects that are connected in some way to J.B. Yeats (A6630)
Filter by depiction¶
This lets you filter object records by the person, place, or concept depicted in an object
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_depicts=A6630')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} object(s) that depict J.B. Yeats (A6630)")
There are 1 object(s) that depict J.B. Yeats (A6630)
Filter by maker¶
This lets you filter object records by the maker of an object (this can be one of a person, a group of people, or an organisation)
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_maker=A6630')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that are made by J.B. Yeats (A6630)")
There are 11 objects that are made by J.B. Yeats (A6630)
Filter by place¶
This lets you filter object records by a place where an object was made, depicts or is otherwise associated with.
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_place=x37151')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that are from, depict or are associated with the place 'Redcar and Cleveland'")
There are 7 objects that are from, depict or are associated with the place 'Redcar and Cleveland'
Filter by category¶
This lets you filter object records by a categorisation applied to an object.
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_category=THES49002')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that are categorised as 'Gardens & Gardening'")
There are 2254 objects that are categorised as 'Gardens & Gardening'
Filter by collection¶
This lets you filter object records by the collecting department in the museum that manages an object.
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_collection=THES260586')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} objects that are part of the 'Digital, Architecture and Design' department")
There are 798 objects that are part of the 'Digital, Architecture and Design' department
Filter by association¶
This lets you filter object records by a person, place, people, organisation associated with an object.
import requests
req = requests.get('https://api.vam.ac.uk/v2/objects/search?id_associated=A8575')
object_data = req.json()
object_info = object_data["info"]
object_records = object_data["records"]
record_count = object_info["record_count"]
print(f"There are {record_count} object(s) with which William Kent (A8575) is associated (but not neccessarily as the maker of the object and/or depicted in the object)")
There are 1 object(s) with which William Kent (A8575) is associated (but not neccessarily as the maker of the object and/or depicted in the object)
Advanced Topics¶
Boolean support within filtering¶
You might be thinking another way to exactly specify multiple filters is to provide support for Boolean Searching operators within a filter parameter. For example using id_person=”A6630|A6631” to indicate you want object records mentioning either A6630 or A6631 or both of them. You might also think you could further extend this to even more complex filtering by using boolean operators in multiple parameters (id_person, id_material, etc); to specify the way you want filters to be combined (e.g. applying boolean AND between fields (‘narrowing’) and boolean OR within a repeating field (‘broadening’), except for the materials field where boolean negation applies, except for material type silver which must be present on all matching object records. You would rightly think this would then provide you with a more granular way to control the search mode, per field instead of forcing them all to be “broad” or “narrow” combinations as the “search_mode” parameter does at present.
You might think all this, but at present it is not supported.