Vector Search / Nearest Neighbors

Vector search systems with Vi is designed to be incredibly easy to do.

Let us write a quick function to show the results as pandas DataFrames.

[6]:
import os
username = os.environ['VI_USERNAME']
api_key = os.environ['VI_API_KEY']
url = "https://api.vctr.ai"
[7]:
collection_name = 'ecommerce'
[9]:
from vectorai.client import ViClient
vi_client = ViClient(username, api_key, url)

from vectorai.models.deployed import ViText2Vec, ViImage2Vec, ViAudio2Vec
text_encoder = ViText2Vec(username, api_key, 'https://api.vctr.ai')
image_encoder = ViImage2Vec(username, api_key, 'https://api.vctr.ai')

Here we insert the documents into a collection and encode it with a text2vec encoder. When a field is encoded a new field is created called ‘field_vector_’. e.g. ‘name’ -> ‘name_vector_’

[6]:
vi_client.insert_documents(
    collection_name,
    documents,
    models={
        'name':text_encoder.encode,
    }
)

Once inserted you can also run jobs ontop of the collection to encode other fields that you didn’t encode intially at insert.

[7]:
job = vdb_client.encode_image_job(collection_name, 'image_url')
vdb_client.wait_till_jobs_complete(collection_name, job['job_id'], job['job_name'])

Collection Metadata

View the collection schema.

[12]:
vi_client.collection_schema(collection_name)
[12]:
{'_clusters_': 'dict',
 '_clusters_.image_url_vector_': 'dict',
 '_clusters_.image_url_vector_.default': 'numeric',
 '_clusters_.name_vector_': 'dict',
 '_clusters_.name_vector_.default': 'numeric',
 '_dr_': 'dict',
 '_dr_.default': 'dict',
 '_dr_.default.2': 'dict',
 '_dr_.default.2.name_vector_': 'vector',
 '_dr_.default.2048': 'dict',
 '_dr_.default.2048.image_url_vector_': 'vector',
 'add_to_cart_html': 'text',
 'attribute_set': 'text',
 'brand_img': 'text',
 'cashback_amount': 'text',
 'cashback_time': 'numeric',
 'categories': 'numeric',
 'categories_search': 'text',
 'clearance_item': 'text',
 'compare_url': 'text',
 'description': 'text',
 'description_vector_': 'vector',
 'display_url_vector_': 'vector',
 'id': 'text',
 'image_url': 'text',
 'image_url_vector_': 'vector',
 'insert_date_': 'date',
 'manufacturer': 'text',
 'memory_gb': 'text',
 'merchandising_blocks': 'text',
 'model_no': 'text',
 'name': 'text',
 'name_vector_': 'vector',
 'objectID': 'text',
 'on_special': 'bool',
 'pre_order': 'numeric',
 'price': 'numeric',
 'price_html': 'text',
 'product_url': 'text',
 'quickview_url': 'text',
 'rating': 'text',
 'saleable': 'numeric',
 'short_description': 'text',
 'sku': 'text',
 'special_time': 'numeric',
 'status': 'text',
 'store_id': 'numeric',
 'tax_class_id': 'text',
 'thumbnail_url': 'text',
 'ticket_price': 'text',
 'was_now': 'text',
 'webcode': 'text'}

View statistics about your collection!

[13]:
vi_client.collection_stats(collection_name)
[13]:
{'size_mb': 756.213328,
 'number_of_documents': 6068,
 'number_of_searches': 32698,
 'number_of_id_lookups': 30519}

List all created collections!

[14]:
vi_client.list_collections()[0:5]
[14]:
['aggregated_ecommerce',
 'audio_quickstart',
 'common_voice',
 'ecommerce',
 'instagram']

Displaying a document by its id and without vectors.

[15]:
document = vi_client.id(collection_name, '1_50198', include_vector=False)
document.keys()
document['sku'], document['name'], document['description'], document['categories'], document['manufacturer']
[15]:
dict_keys(['short_description', 'on_special', 'categories_search', 'product_url', 'rating', 'description', 'saleable', 'pre_order', 'thumbnail_url', 'model_no', 'was_now', 'manufacturer', 'cashback_amount', 'price', 'merchandising_blocks', 'add_to_cart_html', 'attribute_set', 'id', 'categories', 'sku', 'brand_img', 'store_id', 'quickview_url', 'compare_url', 'price_html', 'ticket_price', 'image_url', 'tax_class_id', 'insert_date_', 'clearance_item', 'cashback_time', 'memory_gb', 'webcode', 'special_time', 'name', '_clusters_', 'objectID', '_dr_', 'status'])
[15]:
('MV7N2ZA/A',
 'Apple AirPods with Charging Case (2nd Gen) - MV7N2ZA/A',
 'Designed by Apple<br />Automatically on, automatically connected<br />Easy setup for all your Apple devices6<br />Quick access to Siri<br />Double tap to play or skip forward<br />Charges quickly in the case<br />Case can be charged with a Lightning connector<br />Rich, high-quality audio and voice<br />Seamless switching between devices<br /><br />Accessibility: Live Listen audio<br />AirPods sensors (each): Dual beamforming microphones, Dual optical sensors, Motion-detecting accelerometer, Speech-detecting accelerometer<br /><br />AirPods: Bluetooth<br />Charging case: Lightning connector<br /><br />AirPods with charging case: More than 24 hours of listening time3, up to 18 hours of talk time<br />AirPods (single charge): Up to five hours of listening time1, up to three hours of talk time; 15 minutes in the case equals three hours of listening time4 or up to two hours of talk time<br /><br />iPhone, iPad and iPod touch models: With iOS 12.2 or later<br />Apple Watch models: With watchOS 5.2 or later<br />Mac models: With macOS 10.14.4 or later<br />Apple TV models: With tvOS 12.2 or later<br /><br />iPhone Models: iPhone XS, iPhone XS Max, iPhone XR, iPhone X, iPhone 8, iPhone 8 Plus, iPhone 7, iPhone 7 Plus, iPhone 6s, iPhone 6s Plus, iPhone 6, iPhone 6 Plus, iPhone SE, iPhone 5s<br />iPad Models: iPad Air (3rd generation), iPad mini (5th generation), 11-inch iPad Pro, 12.9-inch iPad Pro (3rd generation), 10.5-inch iPad Pro, iPad (6th Generation), iPad (5th Generation), iPad Pro 12.9-inch (2nd Generation), iPad Pro 12.9-inch (1st Generation), iPad Pro 9.7-inch, iPad mini 4, iPad mini 3, iPad mini 2, iPad Air 2, iPad Air (1st generation)<br />Mac Models: 12-inch MacBook, 13-inch MacBook Air with Retina display, 13-inch MacBook Air, 11-inch MacBook Air, 13-inch MacBook Pro - Thunderbolt 3 (USB-C), 13-inch MacBook Pro, 15-inch MacBook Pro - Thunderbolt 3 (USB-C), 15-inch MacBook Pro, 21.5-inch iMac — Thunderbolt 3 (USB-C), 21.5-inch iMac — Thunderbolt 2, 27-inch iMac — Thunderbolt 3 (USB-C), 27-inch iMac — Thunderbolt 2, iMac Pro, Mac Pro, Mac mini — Thunderbolt 3 (USB-C), Mac mini<br />Watch Models: Series 4, Series 3, Series 2, Series 1<br />Apple TV Models: Apple TV 4K, Apple TV HD<br />iPod Models: iPod touch (6th Generation)<br />',
 [1261, 4, 31, 1300, 1394, 1395, 2048, 2197, 2219, 2226, 1132, 2379],
 'Apple')

Vector based Recommendations (Search by Id)

Vector-based recommendations is the same as search with one minor difference - we use the id associated with the vector of “x” document for search.

Single Item Recommendation (One -> Many)

I liked product A, recommend me products similar to it, or products that users also bought

What is happening here is that the vector of product A stored in VecDB is used as a search query:

\(Vector_{ProductA} = Search Query\)

[47]:
product_id = '1_50017'

results = vi_client.search_by_id(collection_name, product_id, 'name_vector_', page_size=10)
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'],
    nrows=10, image_width=80)
[47]:
image_url _id name sku
0 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
1 1_49987 DeLonghi - CTOC 2003.R - Icona Capitals 2 Slice Toaster - Tokyo Red CTOC2003R
2 1_50016 DeLonghi - CTOC 2003.BL - Icona Capitals 2 Slice Toaster - London Blue CTOC2003BL
3 1_49988 DeLonghi - CTOC 2003.W - Icona Capitals 2 Slice Toaster - Sydney White CTOC2003W
4 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y
5 1_50021 DeLonghi - KBOC 2001.Y - Icona Capitals Kettle - New York Yellow KBOC2001Y
6 1_50032 DeLonghi - CTOC 4003.BL - Icona Capitals 4 Slice Toaster - London Blue CTOC4003BL
7 1_49989 DeLonghi - CTOC 4003.R - Icona Capitals 4 Slice Toaster - Tokyo Red CTOC4003R
8 1_52910 DeLonghi - CTOC 4003.O - Icona Capitals 4 Slice Toaster - Rome Orange CTOC4003O
9 1_49990 DeLonghi - CTOC 4003.W - Icona Capitals 4 Slice Toaster - Sydney White CTOC4003W

Advanced Recommendations With Multiple Vectors

[51]:
results = vi_client.advanced_search_by_id(collection_name, product_id,
                                          {'name_vector_':1, 'image_url_vector_':1}, page_size=3)['results']
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'], image_width=150)
[51]:
image_url _id name sku
0 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
1 1_49987 DeLonghi - CTOC 2003.R - Icona Capitals 2 Slice Toaster - Tokyo Red CTOC2003R
2 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y

Multi Item Recommendations (Many -> Many)

e.g. I liked product A+B, recommend me products similar to it

e.g. A like Product A only about 7/10, I like Product B 10/10

\(0.7\times Vector_{ProductA} + 1\times Vector_{ProductB} = Search Query\)

Recommendations for multiple products.

[54]:
results = vi_client.search_by_ids(collection_name, ['1_50017', '1_50021'], 'name_vector_', page_size=5)
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'], image_width=100)
[54]:
image_url _id name sku
0 1_50021 DeLonghi - KBOC 2001.Y - Icona Capitals Kettle - New York Yellow KBOC2001Y
1 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
2 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y
3 1_50016 DeLonghi - CTOC 2003.BL - Icona Capitals 2 Slice Toaster - London Blue CTOC2003BL
4 1_49987 DeLonghi - CTOC 2003.R - Icona Capitals 2 Slice Toaster - Tokyo Red CTOC2003R

Advanced Recommendations With Multiple Vectors For Multiple Products

[55]:
results = vi_client.advanced_search_by_ids(collection_name, {'1_50017':1, '1_50021':1},
                                           {'name_vector_':1, 'image_url_vector_':1},
                                           page_size=5, vector_operation='mean')
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'], image_width=100)
[55]:
image_url _id name sku
0 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
1 1_50021 DeLonghi - KBOC 2001.Y - Icona Capitals Kettle - New York Yellow KBOC2001Y
2 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y
3 1_52912 DeLonghi - KBOC 2001.O - Icona Capitals Kettle - Rome Orange KBOC2001O
4 1_49987 DeLonghi - CTOC 2003.R - Icona Capitals 2 Slice Toaster - Tokyo Red CTOC2003R

I liked product A+B but not product C, recommend me products based off that

\(Vector_{ProductA} + Vector_{ProductB} - Vector_{ProductC} = Search Query\)

Recommendations from multiple products/Search by IDs

[57]:
results = vi_client.advanced_search_by_positive_negative_ids(collection_name,
    {'1_50017':1, '1_50018':1}, {'1_50021':1},
    {'name_vector_':1}, page_size=5,
    vector_operation='sum')
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'], image_width=150)
[57]:
image_url _id name sku
0 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y
1 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
2 1_49989 DeLonghi - CTOC 4003.R - Icona Capitals 4 Slice Toaster - Tokyo Red CTOC4003R
3 1_52910 DeLonghi - CTOC 4003.O - Icona Capitals 4 Slice Toaster - Rome Orange CTOC4003O
4 1_50032 DeLonghi - CTOC 4003.BL - Icona Capitals 4 Slice Toaster - London Blue CTOC4003BL

Combining Query + Recommendation

Recommendations/Users like and dislike history can be embedded in a search query

\(Serch Query + Vector_{ProductA} + Vector_{ProductB} - Vector_{ProductC} = New Search Query\)

[58]:
results = vi_client.advanced_search_with_positive_negative_ids_as_history(
    collection_name,
    text_encoder.encode('Delonghi'),
    positive_document_ids={'1_50017':1, '1_50018':1},
    negative_document_ids={'1_50021':1},
    fields={'name_vector_':1},
    page_size=5,
    vector_operation='sum')
vi_client.show_json(results, selected_fields=['_id', 'name', 'sku'], image_fields=['image_url'], image_width=100)
[58]:
image_url _id name sku
0 1_50018 DeLonghi - CTOC 4003.Y - Icona Capitals 4 Slice Toaster - New York Yellow CTOC4003Y
1 1_50017 DeLonghi - CTOC 2003.Y - Icona Capitals 2 Slice Toaster - New York Yellow CTOC2003Y
2 1_50032 DeLonghi - CTOC 4003.BL - Icona Capitals 4 Slice Toaster - London Blue CTOC4003BL
3 1_49987 DeLonghi - CTOC 2003.R - Icona Capitals 2 Slice Toaster - Tokyo Red CTOC2003R
4 1_49989 DeLonghi - CTOC 4003.R - Icona Capitals 4 Slice Toaster - Tokyo Red CTOC4003R

Vector Analytics/Aggregation

Traditional aggregation

  1. We randomly create an aggregation_query and use it to aggregate.

  2. This will be the basis for the more advance aggregation enabled by vectors

[37]:
aggregation_query = vi_client.random_aggregation_query(collection_name, groupby=1, metrics=1)
aggregation_query
[37]:
{'groupby': [{'name': 'memory_gb', 'field': 'memory_gb', 'agg': 'texts'}],
 'metrics': [{'name': 'price', 'field': 'price', 'agg': 'avg'}]}

View aggregated results.

[38]:
vi_client.aggregate(collection_name, aggregation_query)
[38]:
[{'memory_gb': '4GB', 'frequency': 5, 'price': 137.0},
 {'memory_gb': '16GB', 'frequency': 3, 'price': 332.3333333333333},
 {'memory_gb': '8GB', 'frequency': 3, 'price': 272.3333333333333},
 {'memory_gb': '8 GB', 'frequency': 2, 'price': 1249.0},
 {'memory_gb': '32GB', 'frequency': 1, 'price': 49.0},
 {'memory_gb': '8GB microSD™ Class 10', 'frequency': 1, 'price': 649.0},
 {'memory_gb': 'Internal solid state', 'frequency': 1, 'price': 149.0},
 {'memory_gb': 'No', 'frequency': 1, 'price': 199.0},
 {'memory_gb': 'microSD', 'frequency': 1, 'price': 3099.0}]
[39]:
aggregation_query = {'groupby': [{'name': 'manufacturer',
   'field': 'manufacturer',
   'agg': 'texts'}],
 'metrics': [{'name': 'price', 'field': 'price', 'agg': 'avg'}]}
vi_client.aggregate(collection_name, aggregation_query)
[39]:
[{'manufacturer': 'Samsung', 'frequency': 356, 'price': 1216.1797752808989},
 {'manufacturer': 'Smeg', 'frequency': 286, 'price': 3285.076923076923},
 {'manufacturer': 'Westinghouse',
  'frequency': 230,
  'price': 1097.9782608695652},
 {'manufacturer': 'Miele', 'frequency': 225, 'price': 3856.133333333333},
 {'manufacturer': 'Cygnett', 'frequency': 180, 'price': 34.19444444444444},
 {'manufacturer': 'Apple', 'frequency': 154, 'price': 985.7922077922078},
 {'manufacturer': 'Philips', 'frequency': 144, 'price': 137.51388888888889},
 {'manufacturer': 'LG', 'frequency': 139, 'price': 1661.4244604316548},
 {'manufacturer': 'Breville', 'frequency': 131, 'price': 325.35114503816794},
 {'manufacturer': 'Panasonic', 'frequency': 129, 'price': 412.8992248062016}]

Aggregations can also be published

  • Product -> Product Search

  • Product -> Brand Search

  • Brand -> Brand Search

[40]:
aggregated_collection_name = 'aggregated_{}'.format(collection_name)
aggregation_name = 'aggregation_{}'.format(collection_name)
[41]:
vi_client.publish_aggregation(collection_name,
                               aggregation_query,
                               aggregation_name=aggregation_name,
                               aggregated_collection_name=aggregated_collection_name,
                               description='some aggregation for {}'.format(collection_name),
                               refresh_time=2,
                               start_immediately=False)
vi_client.start_aggregation(aggregation_name)
[41]:
{'status': 'error',
 'message': 'Something went wrong, please raise the error with maintainer.',
 'error': 'Unknown Error'}
[41]:
{'status': 'complete', 'message': 'aggregation_ecommerce started'}
[42]:
vi_client.results_to_df(vi_client.retrieve_documents(aggregated_collection_name, 3))
[42]:

Basic Vector Analytics

Vector analytics provides an important way to understand how searches work.

[43]:
dr_job = vi_client.dimensionality_reduction_job(collection_name, vector_field='name_vector_', n_components=2)
cluster_job = vi_client.advanced_clustering_job(
    collection_name=collection_name, alias='default', vector_field='name_vector_',
    n_clusters=50, n_init=5)

We can call the wait_till_jobs_complete method

[44]:
vi_client.wait_till_jobs_complete(collection_name, dr_job['job_id'], dr_job['job_name'])
vi_client.wait_till_jobs_complete(collection_name, cluster_job['job_id'], cluster_job['job_name'])

Viewing the advanced cluster facets for only the first cluster:

[45]:
vi_client.advanced_cluster_facets(collection_name, vector_field='name_vector_',
    facets_fields=['manufacturer', 'attribute_set'])['0']
[45]:
{'attribute_set': [{'attribute_set': 'Vacuum Accessories', 'frequency': 19},
  {'attribute_set': 'Stick Vacuum', 'frequency': 15},
  {'attribute_set': 'Undermount Rangehoods', 'frequency': 15},
  {'attribute_set': 'Compact Combi Built-In Microwave', 'frequency': 13},
  {'attribute_set': 'Induction Cooktops', 'frequency': 13},
  {'attribute_set': 'Bagless Vacuum       ', 'frequency': 9},
  {'attribute_set': 'Canopy Rangehoods', 'frequency': 9},
  {'attribute_set': 'Compact Combi Steamers', 'frequency': 9},
  {'attribute_set': 'Warming Draws', 'frequency': 8},
  {'attribute_set': 'All Fridge', 'frequency': 6},
  {'attribute_set': 'Ceramic Cooktop', 'frequency': 6},
  {'attribute_set': 'Dryers', 'frequency': 6},
  {'attribute_set': 'Fixed Rangehoods', 'frequency': 6},
  {'attribute_set': 'Bag Vacuums', 'frequency': 5},
  {'attribute_set': 'Hair Dryers', 'frequency': 5},
  {'attribute_set': 'Upright Vacuum', 'frequency': 5},
  {'attribute_set': '60cm Gas Cooktop', 'frequency': 4},
  {'attribute_set': 'Built-in Coffee Machines', 'frequency': 4},
  {'attribute_set': 'Evaporative Air Cooler', 'frequency': 3},
  {'attribute_set': '60cm Slideout Rangehoods', 'frequency': 2},
  {'attribute_set': '90cm Built-In Ovens', 'frequency': 2},
  {'attribute_set': '90cm Gas Cooktop', 'frequency': 2},
  {'attribute_set': 'Automatic Coffee Maker', 'frequency': 2},
  {'attribute_set': 'Bottom Mount Fridge', 'frequency': 2},
  {'attribute_set': 'Dehumidifiers', 'frequency': 2},
  {'attribute_set': 'Hand Held Floor Cleaners', 'frequency': 2},
  {'attribute_set': 'Shampoo Vacuums', 'frequency': 2},
  {'attribute_set': '70cm Gas Cooktop', 'frequency': 1},
  {'attribute_set': 'Fully Integrated Dishwasher', 'frequency': 1},
  {'attribute_set': 'General Accessories', 'frequency': 1},
  {'attribute_set': 'Hair Straighteners', 'frequency': 1},
  {'attribute_set': 'Other Shelf Appliances', 'frequency': 1},
  {'attribute_set': 'Outdoor Wine', 'frequency': 1},
  {'attribute_set': 'Ovens Upright Duel Fuel 100cm', 'frequency': 1},
  {'attribute_set': 'Rechargeable Vacuum Cleaner', 'frequency': 1},
  {'attribute_set': 'Steam Irons', 'frequency': 1},
  {'attribute_set': 'Vertical Freezers', 'frequency': 1},
  {'attribute_set': 'Washer + Dryer Packages', 'frequency': 1},
  {'attribute_set': 'Wet/Dry Vacuum', 'frequency': 1},
  {'attribute_set': 'Wine Refrigerators', 'frequency': 1}],
 'manufacturer': [{'manufacturer': 'Miele', 'frequency': 138},
  {'manufacturer': 'Dyson', 'frequency': 21},
  {'manufacturer': 'DeLonghi', 'frequency': 4},
  {'manufacturer': 'LG', 'frequency': 4},
  {'manufacturer': 'Shark', 'frequency': 4},
  {'manufacturer': 'Honeywell', 'frequency': 3},
  {'manufacturer': 'Samsung', 'frequency': 3},
  {'manufacturer': 'Bissell', 'frequency': 2},
  {'manufacturer': 'Numatic International', 'frequency': 2},
  {'manufacturer': 'Remington', 'frequency': 2},
  {'manufacturer': 'Vax', 'frequency': 2},
  {'manufacturer': 'Black & Decker', 'frequency': 1},
  {'manufacturer': 'Bosch', 'frequency': 1},
  {'manufacturer': 'FoodSaver', 'frequency': 1},
  {'manufacturer': 'Unilux', 'frequency': 1}]}

Viewing the cluster aggregation statistics.

[46]:
vi_client.advanced_cluster_aggregate(
    collection_name,
    aggregation_query,
    vector_field='name_vector_')['0']
[46]:
[{'manufacturer': 'Miele', 'frequency': 138, 'price': 3647.804347826087},
 {'manufacturer': 'Dyson', 'frequency': 21, 'price': 625.0},
 {'manufacturer': 'DeLonghi', 'frequency': 4, 'price': 1174.0},
 {'manufacturer': 'LG', 'frequency': 4, 'price': 896.0},
 {'manufacturer': 'Shark', 'frequency': 4, 'price': 399.0},
 {'manufacturer': 'Honeywell', 'frequency': 3, 'price': 449.0},
 {'manufacturer': 'Samsung', 'frequency': 3, 'price': 965.6666666666666},
 {'manufacturer': 'Bissell', 'frequency': 2, 'price': 349.0},
 {'manufacturer': 'Numatic International', 'frequency': 2, 'price': 849.0},
 {'manufacturer': 'Remington', 'frequency': 2, 'price': 184.0}]
[47]:
vi_client.advanced_cluster_aggregate(
    collection_name,
    aggregation_query,
    vector_field='name_vector_')['1']
[47]:
[{'manufacturer': 'Targus', 'frequency': 22, 'price': 34.45454545454545},
 {'manufacturer': 'Blanco', 'frequency': 9, 'price': 636.7777777777778},
 {'manufacturer': 'STM', 'frequency': 7, 'price': 63.285714285714285},
 {'manufacturer': 'Tauris', 'frequency': 1, 'price': 599.0}]
[48]:
vi_client.plot_dimensionality_reduced_vectors(
    collection=collection_name,
    cluster_field='name_vector_',
    cluster_label='_clusters_.name_vector_.default',
    point_label='name',
    dim_reduction_field='_dr_.default.2.name_vector_',
    include_centroids=True,
    alias='default')