Source: https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/nearest-neighbor/ Documentation version: v5.3.2 # 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)](https://en.wikipedia.org/wiki/Nearest_neighbor_search#k-nearest_neighbors) search and [approximate nearest neighbor (ANN)](https://en.wikipedia.org/wiki/Nearest_neighbor_search#Approximate_nearest_neighbor) 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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-vector/). ## Syntax diagramsource knn_search_statement ann_search_statement ann_search_option ```` 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()](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/functions/vector/#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()](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/functions/vector/#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()](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/functions/vector/#cosine): If used, only KNN searches are supported. For more information, see [ORDER BY](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/clauses/order-by/). ### `limit_clause` The clause that limits the number of search results to return. For more information, see [LIMIT](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/dql/clauses/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()](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/functions/vector/#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()](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/functions/vector/#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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-vector/). #### `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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/index/create-vector/#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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph-type/create/). ```` 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 | +-----+--------+------------------+----------+ ````