Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

Nearest neighbor query statements

The nearest neighbor query statements search for the nearest neighbors of a query vector in a graph. The statements support two types of searches: k-nearest neighbor (KNN) search and approximate nearest neighbor (ANN) search.

KNN is an exact search that returns the k nearest neighbors of the query vector. It does not rely on vector indexes and is suitable for small-sized graphs and low-dimensional vectors.

ANN is an approximate search that returns the approximate nearest neighbors of the query vector. It relies on vector indexes and is suitable for large-sized graphs and high-dimensional vectors.

To perform ANN searches, you must create vector indexes on the vectors to be searched beforehand; otherwise, ANN searches are automatically converted to KNN searches. For more information, see CREATE VECTOR INDEX.

Syntax

knn_search_statement
order_by_clause limit_clause
ann_search_statement
order_by_clause APPROX APPROXIMATE limit_clause OPTIONS { ann_search_option , }
ann_search_option
METRIC : L2 IP TYPE : IVF HNSW NPROBE : int_value EFSEARCH : int_value

knn_search_statement ::= order_by_clause limit_clause 

ann_search_statement ::= order_by_clause ('APPROX'| 'APPROXIMATE') limit_clause ('OPTIONS' '{' ann_search_option (',' ann_search_option)* '}' )

ann_search_option::=  
    'METRIC' ':' ( 'L2' | 'IP' )
  | 'TYPE' ':' ( 'IVF' | 'HNSW' )
  | 'NPROBE' ':' int_value
  | 'EFSEARCH' ':' int_value

Parameters

order_by_clause

The clause that sorts the search results based on the similarity between the query vector and indexed vectors. The clause must include one function that measures the similarity between vectors.

The following functions are supported:

  • euclidean(): If used in an ANN search, ensure the following conditions are met:
    • A vector index based on metric L2 is already created on the searched vectors; otherwise, the ANN search is automatically converted to a KNN search.
    • The search results are sorted in ascending order.
  • inner_product(): If used in an ANN search, ensure the following conditions are met:
    • A vector index based on metric IP is already created on the searched vectors; otherwise, the ANN search is automatically converted to a KNN search.
    • The search results are sorted in descending order.
  • cosine(): If used, only KNN searches are supported.

For more information, see ORDER BY.

limit_clause

The clause that limits the number of search results to return. For more information, see LIMIT.

ann_search_option

The options for performing ANN searches.

METRIC

The metric used to measure the similarity between the query vector and indexed vectors. The value is automatically set based on the function specified in the preceding order_by_clause as follows:

  • If the function is euclidean(), the metric is set to L2 by default, which measures the similarity between vectors based on the Euclidean distance between them. For more information, see euclidean().
  • If the function is inner_product(), the metric is set to IP by default, which measures the similarity between vectors based on the inner product between them. For more information, see inner_product().

If you specify a value that contradicts the function specified in the preceding order_by_clause, an error occurs.

TYPE

The type of vector index to use for the ANN search. Valid values are: IVF and HNSW. If not specified, the default value IVF applies. For more information, see CREATE VECTOR INDEX.

NPROBE

The number of clusters to search during an IVF search. This option takes effect only when the option TYPE is set to IVF.

This option controls the trade-off between the search speed and the search accuracy in the IVF algorithm. A larger value results in a higher search accuracy but a slower search speed.

The valid value ranges from 1 to NLIST, where NLIST refers to the number of clusters created when the IVF index is created. For more information, see NLIST.

If NPROBE is set to the same value as NLIST, theoretically the best recall is achieved, but the search speed is the slowest.

If you do not specify this option while TYPE is set to IVF, the default value 8 applies.

EFSEARCH

The size of the dynamic candidate list during an HNSW search, which determines the number of neighbors explored during the search. This option takes effect only when the option TYPE is set to HNSW.

This option controls the trade-off between the search speed and the search accuracy in the HNSW algorithm. A larger value results in a higher search accuracy but a slower search speed.

The valid value ranges from 1 to infinity.

If you do not specify this option while TYPE is set to HNSW, the default value 16 applies.

Examples

The following example provides step-by-step instructions on how to perform KNN and ANN searches in a graph:

  1. Create a graph based on the graph type ann_test created in CREATE GRAPH TYPE.

    CREATE GRAPH IF NOT EXISTS ann_test_graph TYPED ann_test    
    
  2. Insert nodes and edges into the graph ann_test_graph.

    '''
    // Insert 27 nodes of node type `N1` into the graph.
    TABLE t {id, vec1, vec2, vec3} =   
        {id:1, vec1:VECTOR<3,float>([1.0, 2.0, 3.0]), vec2:VECTOR<7,float>([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]), vec3:VECTOR<3,float>([1.0, 2.0, 3.0])}, 
        {id:2, vec1:VECTOR<3,float>([2.0, 3.0, 4.0]), vec2:VECTOR<7,float>([2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]), vec3:VECTOR<3,float>([2.0, 3.0, 4.0])}, 
        {id:3, vec1:VECTOR<3,float>([3.0, 4.0, 5.0]), vec2:VECTOR<7,float>([3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]), vec3:VECTOR<3,float>([3.0, 4.0, 5.0])}, 
        {id:4, vec1:VECTOR<3,float>([4.0, 5.0, 6.0]), vec2:VECTOR<7,float>([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]), vec3:VECTOR<3,float>([4.0, 5.0, 6.0])}, 
        {id:5, vec1:VECTOR<3,float>([5.0, 6.0, 7.0]), vec2:VECTOR<7,float>([5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0]), vec3:VECTOR<3,float>([5.0, 6.0, 7.0])}, 
        {id:6, vec1:VECTOR<3,float>([6.0, 7.0, 8.0]), vec2:VECTOR<7,float>([6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]), vec3:VECTOR<3,float>([6.0, 7.0, 8.0])}, 
        {id:7, vec1:VECTOR<3,float>([7.0, 8.0, 9.0]), vec2:VECTOR<7,float>([7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0]), vec3:VECTOR<3,float>([7.0, 8.0, 9.0])}, 
        {id:8, vec1:VECTOR<3,float>([8.0, 9.0, 10.0]), vec2:VECTOR<7,float>([8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0]), vec3:VECTOR<3,float>([8.0, 9.0, 10.0])}, 
        {id:9, vec1:VECTOR<3,float>([9.0, 10.0, 11.0]), vec2:VECTOR<7,float>([9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0]), vec3:VECTOR<3,float>([9.0, 10.0, 11.0])}, 
        {id:10, vec1:VECTOR<3,float>([10.0, 11.0, 12.0]), vec2:VECTOR<7,float>([10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]), vec3:VECTOR<3,float>([10.0, 11.0, 12.0])}, 
        {id:11, vec1:VECTOR<3,float>([11.0, 12.0, 13.0]), vec2:VECTOR<7,float>([11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0]), vec3:VECTOR<3,float>([11.0, 12.0, 13.0])}, 
        {id:12, vec1:VECTOR<3,float>([12.0, 13.0, 14.0]), vec2:VECTOR<7,float>([12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0]), vec3:VECTOR<3,float>([12.0, 13.0, 14.0])}, 
        {id:13, vec1:VECTOR<3,float>([13.0, 14.0, 15.0]), vec2:VECTOR<7,float>([13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0]), vec3:VECTOR<3,float>([13.0, 14.0, 15.0])}, 
        {id:14, vec1:VECTOR<3,float>([14.0, 15.0, 16.0]), vec2:VECTOR<7,float>([14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]), vec3:VECTOR<3,float>([14.0, 15.0, 16.0])}, 
        {id:15, vec1:VECTOR<3,float>([15.0, 16.0, 17.0]), vec2:VECTOR<7,float>([15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0]), vec3:VECTOR<3,float>([15.0, 16.0, 17.0])}, 
        {id:16, vec1:VECTOR<3,float>([16.0, 17.0, 18.0]), vec2:VECTOR<7,float>([16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0]), vec3:VECTOR<3,float>([16.0, 17.0, 18.0])}, 
        {id:17, vec1:VECTOR<3,float>([17.0, 18.0, 19.0]), vec2:VECTOR<7,float>([17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0]), vec3:VECTOR<3,float>([17.0, 18.0, 19.0])}, 
        {id:18, vec1:VECTOR<3,float>([18.0, 19.0, 20.0]), vec2:VECTOR<7,float>([18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0]), vec3:VECTOR<3,float>([18.0, 19.0, 20.0])}, 
        {id:19, vec1:VECTOR<3,float>([19.0, 20.0, 21.0]), vec2:VECTOR<7,float>([19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0]), vec3:VECTOR<3,float>([19.0, 20.0, 21.0])}, 
        {id:20, vec1:VECTOR<3,float>([20.0, 21.0, 22.0]), vec2:VECTOR<7,float>([20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0]), vec3:VECTOR<3,float>([20.0, 21.0, 22.0])}, 
        {id:21, vec1:VECTOR<3,float>([21.0, 22.0, 23.0]), vec2:VECTOR<7,float>([21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0]), vec3:VECTOR<3,float>([21.0, 22.0, 23.0])}, 
        {id:22, vec1:VECTOR<3,float>([22.0, 23.0, 24.0]), vec2:VECTOR<7,float>([22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0]), vec3:VECTOR<3,float>([22.0, 23.0, 24.0])}, 
        {id:23, vec1:VECTOR<3,float>([23.0, 24.0, 25.0]), vec2:VECTOR<7,float>([23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0]), vec3:VECTOR<3,float>([23.0, 24.0, 25.0])}, 
        {id:24, vec1:VECTOR<3,float>([24.0, 25.0, 26.0]), vec2:VECTOR<7,float>([24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0]), vec3:VECTOR<3,float>([24.0, 25.0, 26.0])}, 
        {id:25, vec1:VECTOR<3,float>([25.0, 26.0, 27.0]), vec2:VECTOR<7,float>([25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0]), vec3:VECTOR<3,float>([25.0, 26.0, 27.0])}, 
        {id:26, vec1:VECTOR<3,float>([26.0, 27.0, 28.0]), vec2:VECTOR<7,float>([26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0]), vec3:VECTOR<3,float>([26.0, 27.0, 28.0])}, 
        {id:27, vec1:VECTOR<3,float>([27.0, 28.0, 29.0]), vec2:VECTOR<7,float>([27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0]), vec3:VECTOR<3,float>([27.0, 28.0, 29.0])} 
    USE ann_test_graph 
    FOR r IN t 
    INSERT OR IGNORE (@N1{id:r.id,vec1:r.vec1,vec2:r.vec2,vec3:r.vec3})
    '''
    
    '''
    // Insert 19 nodes of node type `N2` into the graph.
    TABLE t {id, vec1, vec2, vec5} = 
        {id:1, vec1:VECTOR<3,float>([1.1, 2.1, 3.1]), vec2:VECTOR<7,float>([1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2]), vec5:VECTOR<5,float>([1.3, 2.3, 3.3, 4.3, 5.3])}, 
        {id:2, vec1:VECTOR<3,float>([2.1, 3.1, 4.1]), vec2:VECTOR<7,float>([2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 8.2]), vec5:VECTOR<5,float>([2.3, 3.3, 4.3, 5.3, 6.3])}, 
        {id:3, vec1:VECTOR<3,float>([3.1, 4.1, 5.1]), vec2:VECTOR<7,float>([3.2, 4.2, 5.2, 6.2, 7.2, 8.2, 9.2]), vec5:VECTOR<5,float>([3.3, 4.3, 5.3, 6.3, 7.3])}, 
        {id:4, vec1:VECTOR<3,float>([4.1, 5.1, 6.1]), vec2:VECTOR<7,float>([4.2, 5.2, 6.2, 7.2, 8.2, 9.2, 10.2]), vec5:VECTOR<5,float>([4.3, 5.3, 6.3, 7.3, 8.3])}, 
        {id:5, vec1:VECTOR<3,float>([5.1, 6.1, 7.1]), vec2:VECTOR<7,float>([5.2, 6.2, 7.2, 8.2, 9.2, 10.2, 11.2]), vec5:VECTOR<5,float>([5.3, 6.3, 7.3, 8.3, 9.3])}, 
        {id:6, vec1:VECTOR<3,float>([6.1, 7.1, 8.1]), vec2:VECTOR<7,float>([6.2, 7.2, 8.2, 9.2, 10.2, 11.2, 12.2]), vec5:VECTOR<5,float>([6.3, 7.3, 8.3, 9.3, 10.3])}, 
        {id:7, vec1:VECTOR<3,float>([7.1, 8.1, 9.1]), vec2:VECTOR<7,float>([7.2, 8.2, 9.2, 10.2, 11.2, 12.2, 13.2]), vec5:VECTOR<5,float>([7.3, 8.3, 9.3, 10.3, 11.3])}, 
        {id:8, vec1:VECTOR<3,float>([8.1, 9.1, 10.1]), vec2:VECTOR<7,float>([8.2, 9.2, 10.2, 11.2, 12.2, 13.2, 14.2]), vec5:VECTOR<5,float>([8.3, 9.3, 10.3, 11.3, 12.3])}, 
        {id:9, vec1:VECTOR<3,float>([9.1, 10.1, 11.1]), vec2:VECTOR<7,float>([9.2, 10.2, 11.2, 12.2, 13.2, 14.2, 15.2]), vec5:VECTOR<5,float>([9.3, 10.3, 11.3, 12.3, 13.3])}, 
        {id:10, vec1:VECTOR<3,float>([10.1, 11.1, 12.1]), vec2:VECTOR<7,float>([10.2, 11.2, 12.2, 13.2, 14.2, 15.2, 16.2]), vec5:VECTOR<5,float>([10.3, 11.3, 12.3, 13.3, 14.3])}, 
        {id:11, vec1:VECTOR<3,float>([11.1, 12.1, 13.1]), vec2:VECTOR<7,float>([11.2, 12.2, 13.2, 14.2, 15.2, 16.2, 17.2]), vec5:VECTOR<5,float>([11.3, 12.3, 13.3, 14.3, 15.3])}, 
        {id:12, vec1:VECTOR<3,float>([12.1, 13.1, 14.1]), vec2:VECTOR<7,float>([12.2, 13.2, 14.2, 15.2, 16.2, 17.2, 18.2]), vec5:VECTOR<5,float>([12.3, 13.3, 14.3, 15.3, 16.3])}, 
        {id:13, vec1:VECTOR<3,float>([13.1, 14.1, 15.1]), vec2:VECTOR<7,float>([13.2, 14.2, 15.2, 16.2, 17.2, 18.2, 19.2]), vec5:VECTOR<5,float>([13.3, 14.3, 15.3, 16.3, 17.3])}, 
        {id:14, vec1:VECTOR<3,float>([14.1, 15.1, 16.1]), vec2:VECTOR<7,float>([14.2, 15.2, 16.2, 17.2, 18.2, 19.2, 20.2]), vec5:VECTOR<5,float>([14.3, 15.3, 16.3, 17.3, 18.3])}, 
        {id:15, vec1:VECTOR<3,float>([15.1, 16.1, 17.1]), vec2:VECTOR<7,float>([15.2, 16.2, 17.2, 18.2, 19.2, 20.2, 21.2]), vec5:VECTOR<5,float>([15.3, 16.3, 17.3, 18.3, 19.3])}, 
        {id:16, vec1:VECTOR<3,float>([16.1, 17.1, 18.1]), vec2:VECTOR<7,float>([16.2, 17.2, 18.2, 19.2, 20.2, 21.2, 22.2]), vec5:VECTOR<5,float>([16.3, 17.3, 18.3, 19.3, 20.3])}, 
        {id:17, vec1:VECTOR<3,float>([17.1, 18.1, 19.1]), vec2:VECTOR<7,float>([17.2, 18.2, 19.2, 20.2, 21.2, 22.2, 23.2]), vec5:VECTOR<5,float>([17.3, 18.3, 19.3, 20.3, 21.3])}, 
        {id:18, vec1:VECTOR<3,float>([18.1, 19.1, 20.1]), vec2:VECTOR<7,float>([18.2, 19.2, 20.2, 21.2, 22.2, 23.2, 24.2]), vec5:VECTOR<5,float>([18.3, 19.3, 20.3, 21.3, 22.3])}, 
        {id:19, vec1:VECTOR<3,float>([19.1, 20.1, 21.1]), vec2:VECTOR<7,float>([19.2, 20.2, 21.2, 22.2, 23.2, 24.2, 25.2]), vec5:VECTOR<5,float>([19.3, 20.3, 21.3, 22.3, 23.3])} 
    USE ann_test_graph 
    FOR r IN t 
    INSERT OR IGNORE (@N2{id:r.id,vec1:r.vec1,vec2:r.vec2,vec5:r.vec5})
    '''
    
    '''
    // Insert 27 edges of edge type `E1` into the graph.
    TABLE t {src, dst, id, vec1, vec2, vec3} = 
        {src: 1, dst:1, id:1, vec1:VECTOR<3,float>([1.11, 2.12, 3.13]), vec2:VECTOR<7,float>([1.21, 2.22, 3.23, 4.24, 5.25, 6.26, 7.27]), vec3:VECTOR<3,float>([1.31, 2.32, 3.33])}, 
        {src: 2, dst:2, id:2, vec1:VECTOR<3,float>([2.11, 3.12, 4.13]), vec2:VECTOR<7,float>([2.21, 3.22, 4.23, 5.24, 6.25, 7.26, 8.27]), vec3:VECTOR<3,float>([2.31, 3.32, 4.33])}, 
        {src: 3, dst:3, id:3, vec1:VECTOR<3,float>([3.11, 4.12, 5.13]), vec2:VECTOR<7,float>([3.21, 4.22, 5.23, 6.24, 7.25, 8.26, 9.27]), vec3:VECTOR<3,float>([3.31, 4.32, 5.33])}, 
        {src: 4, dst:4, id:4, vec1:VECTOR<3,float>([4.11, 5.12, 6.13]), vec2:VECTOR<7,float>([4.21, 5.22, 6.23, 7.24, 8.25, 9.26, 10.27]), vec3:VECTOR<3,float>([4.31, 5.32, 6.33])}, 
        {src: 5, dst:5, id:5, vec1:VECTOR<3,float>([5.11, 6.12, 7.13]), vec2:VECTOR<7,float>([5.21, 6.22, 7.23, 8.24, 9.25, 10.26, 11.27]), vec3:VECTOR<3,float>([5.31, 6.32, 7.33])}, 
        {src: 6, dst:6, id:6, vec1:VECTOR<3,float>([6.11, 7.12, 8.13]), vec2:VECTOR<7,float>([6.21, 7.22, 8.23, 9.24, 10.25, 11.26, 12.27]), vec3:VECTOR<3,float>([6.31, 7.32, 8.33])}, 
        {src: 7, dst:7, id:7, vec1:VECTOR<3,float>([7.11, 8.12, 9.13]), vec2:VECTOR<7,float>([7.21, 8.22, 9.23, 10.24, 11.25, 12.26, 13.27]), vec3:VECTOR<3,float>([7.31, 8.32, 9.33])}, 
        {src: 8, dst:8, id:8, vec1:VECTOR<3,float>([8.11, 9.12, 10.13]), vec2:VECTOR<7,float>([8.21, 9.22, 10.23, 11.24, 12.25, 13.26, 14.27]), vec3:VECTOR<3,float>([8.31, 9.32, 10.33])}, 
        {src: 9, dst:9, id:9, vec1:VECTOR<3,float>([9.11, 10.12, 11.13]), vec2:VECTOR<7,float>([9.21, 10.22, 11.23, 12.24, 13.25, 14.26, 15.27]), vec3:VECTOR<3,float>([9.31, 10.32, 11.33])}, 
        {src: 10, dst:10, id:10, vec1:VECTOR<3,float>([10.11, 11.12, 12.13]), vec2:VECTOR<7,float>([10.21, 11.22, 12.23, 13.24, 14.25, 15.26, 16.27]), vec3:VECTOR<3,float>([10.31, 11.32, 12.33])}, 
        {src: 11, dst:11, id:11, vec1:VECTOR<3,float>([11.11, 12.12, 13.13]), vec2:VECTOR<7,float>([11.21, 12.22, 13.23, 14.24, 15.25, 16.26, 17.27]), vec3:VECTOR<3,float>([11.31, 12.32, 13.33])}, 
        {src: 12, dst:12, id:12, vec1:VECTOR<3,float>([12.11, 13.12, 14.13]), vec2:VECTOR<7,float>([12.21, 13.22, 14.23, 15.24, 16.25, 17.26, 18.27]), vec3:VECTOR<3,float>([12.31, 13.32, 14.33])}, 
        {src: 13, dst:13, id:13, vec1:VECTOR<3,float>([13.11, 14.12, 15.13]), vec2:VECTOR<7,float>([13.21, 14.22, 15.23, 16.24, 17.25, 18.26, 19.27]), vec3:VECTOR<3,float>([13.31, 14.32, 15.33])}, 
        {src: 14, dst:14, id:14, vec1:VECTOR<3,float>([14.11, 15.12, 16.13]), vec2:VECTOR<7,float>([14.21, 15.22, 16.23, 17.24, 18.25, 19.26, 20.27]), vec3:VECTOR<3,float>([14.31, 15.32, 16.33])}, 
        {src: 15, dst:15, id:15, vec1:VECTOR<3,float>([15.11, 16.12, 17.13]), vec2:VECTOR<7,float>([15.21, 16.22, 17.23, 18.24, 19.25, 20.26, 21.27]), vec3:VECTOR<3,float>([15.31, 16.32, 17.33])}, 
        {src: 16, dst:16, id:16, vec1:VECTOR<3,float>([16.11, 17.12, 18.13]), vec2:VECTOR<7,float>([16.21, 17.22, 18.23, 19.24, 20.25, 21.26, 22.27]), vec3:VECTOR<3,float>([16.31, 17.32, 18.33])}, 
        {src: 17, dst:17, id:17, vec1:VECTOR<3,float>([17.11, 18.12, 19.13]), vec2:VECTOR<7,float>([17.21, 18.22, 19.23, 20.24, 21.25, 22.26, 23.27]), vec3:VECTOR<3,float>([17.31, 18.32, 19.33])}, 
        {src: 18, dst:18, id:18, vec1:VECTOR<3,float>([18.11, 19.12, 20.13]), vec2:VECTOR<7,float>([18.21, 19.22, 20.23, 21.24, 22.25, 23.26, 24.27]), vec3:VECTOR<3,float>([18.31, 19.32, 20.33])}, 
        {src: 19, dst:19, id:19, vec1:VECTOR<3,float>([19.11, 20.12, 21.13]), vec2:VECTOR<7,float>([19.21, 20.22, 21.23, 22.24, 23.25, 24.26, 25.27]), vec3:VECTOR<3,float>([19.31, 20.32, 21.33])}, 
        {src: 20, dst:17, id:20, vec1:VECTOR<3,float>([20.11, 21.12, 22.13]), vec2:VECTOR<7,float>([20.21, 21.22, 22.23, 23.24, 24.25, 25.26, 26.27]), vec3:VECTOR<3,float>([20.31, 21.32, 22.33])}, 
        {src: 21, dst:17, id:21, vec1:VECTOR<3,float>([21.11, 22.12, 23.13]), vec2:VECTOR<7,float>([21.21, 22.22, 23.23, 24.24, 25.25, 26.26, 27.27]), vec3:VECTOR<3,float>([21.31, 22.32, 23.33])}, 
        {src: 22, dst:17, id:22, vec1:VECTOR<3,float>([22.11, 23.12, 24.13]), vec2:VECTOR<7,float>([22.21, 23.22, 24.23, 25.24, 26.25, 27.26, 28.27]), vec3:VECTOR<3,float>([22.31, 23.32, 24.33])}, 
        {src: 23, dst:17, id:23, vec1:VECTOR<3,float>([23.11, 24.12, 25.13]), vec2:VECTOR<7,float>([23.21, 24.22, 25.23, 26.24, 27.25, 28.26, 29.27]), vec3:VECTOR<3,float>([23.31, 24.32, 25.33])}, 
        {src: 24, dst:17, id:24, vec1:VECTOR<3,float>([24.11, 25.12, 26.13]), vec2:VECTOR<7,float>([24.21, 25.22, 26.23, 27.24, 28.25, 29.26, 30.27]), vec3:VECTOR<3,float>([24.31, 25.32, 26.33])}, 
        {src: 25, dst:17, id:25, vec1:VECTOR<3,float>([25.11, 26.12, 27.13]), vec2:VECTOR<7,float>([25.21, 26.22, 27.23, 28.24, 29.25, 30.26, 31.27]), vec3:VECTOR<3,float>([25.31, 26.32, 27.33])}, 
        {src: 26, dst:17, id:26, vec1:VECTOR<3,float>([26.11, 27.12, 28.13]), vec2:VECTOR<7,float>([26.21, 27.22, 28.23, 29.24, 30.25, 31.26, 32.27]), vec3:VECTOR<3,float>([26.31, 27.32, 28.33])}, 
        {src: 27, dst:17, id:27, vec1:VECTOR<3,float>([27.11, 28.12, 29.13]), vec2:VECTOR<7,float>([27.21, 28.22, 29.23, 30.24, 31.25, 32.26, 33.27]), vec3:VECTOR<3,float>([27.31, 28.32, 29.33])} 
    USE ann_test_graph 
    FOR r IN t 
    MATCH (n1:N1{id:r.src}), (n2:N2{id:r.dst}) 
    INSERT OR IGNORE (n1)-[@E1{id:r.id,vec1:r.vec1,vec2:r.vec2,vec3:r.vec3}]->(n2)
    '''
    
  3. Create vector indexes on the graph ann_test_graph.

    '''
    // Create an IVF vector index on node type `N1` for vector property `vec1` based on metric `L2`.
    USE ann_test_graph CREATE VECTOR INDEX ann_node_ivf_l2 ON NODE N1::vec1 OPTIONS {DIM: 3, METRIC: L2, TYPE: IVF, NLIST: 10, TRAINSIZE: 4 }
    '''
    
    '''
    // Create an HNSW vector index on node type `N1` for vector property `vec1` based on metric `IP`.
    USE ann_test_graph CREATE VECTOR INDEX ann_node_hnsw_ip ON NODE N1::vec1 OPTIONS {DIM: 3, METRIC: IP, TYPE: HNSW, MAXDEGREE: 3, EFCONSTRUCTION: 6, CAPACITY: 500}
    '''
    
    '''
    // Create an IVF vector index on edge type `E1` for vector property `vec1` based on metric `L2`.
    USE ann_test_graph CREATE VECTOR INDEX ann_edge_ivf_l2 ON EDGE E1::vec1 OPTIONS {DIM: 3, METRIC: L2, TYPE: IVF, NLIST: 10, TRAINSIZE: 4}
    '''
    
    '''
    // Create an HNSW vector index on edge type `E1` for vector property `vec1` based on metric `IP`.
    USE ann_test_graph CREATE VECTOR INDEX ann_edge_hnsw_ip ON EDGE E1::vec1 OPTIONS {DIM: 3, METRIC: IP, TYPE: HNSW, MAXDEGREE: 3, EFCONSTRUCTION: 6, CAPACITY: 500}
    '''
    
  4. Query the graph ann_test_graph to find the nearest neighbors of a given vector.

    • Perform a KNN search to find the nearest neighbors based on euclidean distance

      '''
      USE ann_test_graph 
      MATCH (v:N1) 
      ORDER BY euclidean(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) ASC 
      LIMIT 3 
      RETURN v.id AS vid, labels(v) AS vlabel, v.vec1 AS vec1, euclidean(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) AS distance
      '''
      

      Return:

      +-----+--------+---------------+-----------+
      | vid | vlabel | vec1          | distance  |
      +-----+--------+---------------+-----------+
      | 1   | [N1]   | [1.0,2.0,3.0] | 0.0       |
      | 2   | [N1]   | [2.0,3.0,4.0] | 1.7320508 |
      | 3   | [N1]   | [3.0,4.0,5.0] | 3.4641016 |
      +-----+--------+---------------+-----------+
      

    • Perform a KNN search to find the nearest neighbors based on inner product

      '''
      USE ann_test_graph 
      MATCH (v:N1) 
      ORDER BY inner_product(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) DESC 
      LIMIT 3 
      RETURN v.id AS vid, labels(v) AS vlabel, v.vec1 AS vec1, inner_product(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) AS distance
      '''
      

      Return:

      +-----+--------+------------------+----------+
      | vid | vlabel | vec1             | distance |
      +-----+--------+------------------+----------+
      | 27  | [N1]   | [27.0,28.0,29.0] | 170.0    |
      | 26  | [N1]   | [26.0,27.0,28.0] | 164.0    |
      | 25  | [N1]   | [25.0,26.0,27.0] | 158.0    |
      +-----+--------+------------------+----------+
      

    • Perform an ANN search to find the nearest neighbors based on euclidean distance

      '''
      USE ann_test_graph 
      MATCH (v:N1) 
      ORDER BY euclidean(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) ASC 
      APPROXIMATE 
      LIMIT 3 
      OPTIONS { METRIC: L2, TYPE: IVF, NPROBE: 8 } 
      RETURN v.id AS vid, labels(v) AS vlabel, v.vec1 AS vec1, euclidean(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) AS distance
      '''
      

      Return:

      +-----+--------+---------------+-----------+
      | vid | vlabel | vec1          | distance  |
      +-----+--------+---------------+-----------+
      | 1   | [N1]   | [1.0,2.0,3.0] | 0.0       |
      | 2   | [N1]   | [2.0,3.0,4.0] | 1.7320508 |
      | 3   | [N1]   | [3.0,4.0,5.0] | 3.4641016 |
      +-----+--------+---------------+-----------+
      

    • Perform an ANN search to find the nearest neighbors based on inner product

      '''
      USE ann_test_graph 
      MATCH (v:N1) 
      ORDER BY inner_product(v.vec1, VECTOR<3,float>([1.0, 2.0, 3.0])) DESC 
      APPROXIMATE 
      LIMIT 3 
      OPTIONS { METRIC: IP, TYPE: HNSW, EFSEARCH: 8 } 
      RETURN v.id AS vid, labels(v) AS vlabel, v.vec1 AS vec1, inner_product(v.vec1, VECTOR<3,  float>([1.0, 2.0, 3.0])) AS distance
      '''
      

      Return:

      +-----+--------+------------------+----------+
      | vid | vlabel | vec1             | distance |
      +-----+--------+------------------+----------+
      | 27  | [N1]   | [27.0,28.0,29.0] | 170.0    |
      | 26  | [N1]   | [26.0,27.0,28.0] | 164.0    |
      | 25  | [N1]   | [25.0,26.0,27.0] | 158.0    |
      +-----+--------+------------------+----------+