mirror of
https://github.com/pgvector/pgvector.git
synced 2026-06-06 05:51:21 +08:00
Added support for indexing sparsevec with L1 distance [skip ci]
This commit is contained in:
@@ -483,6 +483,11 @@ CREATE OPERATOR <=> (
|
|||||||
COMMUTATOR = '<=>'
|
COMMUTATOR = '<=>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <+> (
|
||||||
|
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = l1_distance,
|
||||||
|
COMMUTATOR = '<+>'
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR < (
|
CREATE OPERATOR < (
|
||||||
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_lt,
|
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_lt,
|
||||||
COMMUTATOR = > , NEGATOR = >= ,
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
@@ -543,3 +548,8 @@ CREATE OPERATOR CLASS sparsevec_cosine_ops
|
|||||||
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
||||||
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
|
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
|
||||||
FUNCTION 2 l2_norm(sparsevec);
|
FUNCTION 2 l2_norm(sparsevec);
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS sparsevec_l1_ops
|
||||||
|
FOR TYPE sparsevec USING hnsw AS
|
||||||
|
OPERATOR 1 <+> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
||||||
|
FUNCTION 1 l1_distance(sparsevec, sparsevec);
|
||||||
|
|||||||
@@ -804,6 +804,11 @@ CREATE OPERATOR <=> (
|
|||||||
COMMUTATOR = '<=>'
|
COMMUTATOR = '<=>'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR <+> (
|
||||||
|
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = l1_distance,
|
||||||
|
COMMUTATOR = '<+>'
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR < (
|
CREATE OPERATOR < (
|
||||||
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_lt,
|
LEFTARG = sparsevec, RIGHTARG = sparsevec, PROCEDURE = sparsevec_lt,
|
||||||
COMMUTATOR = > , NEGATOR = >= ,
|
COMMUTATOR = > , NEGATOR = >= ,
|
||||||
@@ -866,3 +871,8 @@ CREATE OPERATOR CLASS sparsevec_cosine_ops
|
|||||||
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
OPERATOR 1 <=> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
||||||
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
|
FUNCTION 1 sparsevec_negative_inner_product(sparsevec, sparsevec),
|
||||||
FUNCTION 2 l2_norm(sparsevec);
|
FUNCTION 2 l2_norm(sparsevec);
|
||||||
|
|
||||||
|
CREATE OPERATOR CLASS sparsevec_l1_ops
|
||||||
|
FOR TYPE sparsevec USING hnsw AS
|
||||||
|
OPERATOR 1 <+> (sparsevec, sparsevec) FOR ORDER BY float_ops,
|
||||||
|
FUNCTION 1 l1_distance(sparsevec, sparsevec);
|
||||||
|
|||||||
21
test/expected/hnsw_sparsevec_l1.out
Normal file
21
test/expected/hnsw_sparsevec_l1.out
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
SET enable_seqscan = off;
|
||||||
|
CREATE TABLE t (val sparsevec(3));
|
||||||
|
INSERT INTO t (val) VALUES ('{}/3'), ('{1:1,2:2,3:3}/3'), ('{1:1,2:1,3:1}/3'), (NULL);
|
||||||
|
CREATE INDEX ON t USING hnsw (val sparsevec_l1_ops);
|
||||||
|
INSERT INTO t (val) VALUES ('{1:1,2:2,3:4}/3');
|
||||||
|
SELECT * FROM t ORDER BY val <+> '{1:3,2:3,3:3}/3';
|
||||||
|
val
|
||||||
|
-----------------
|
||||||
|
{1:1,2:2,3:3}/3
|
||||||
|
{1:1,2:2,3:4}/3
|
||||||
|
{1:1,2:1,3:1}/3
|
||||||
|
{}/3
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <+> (SELECT NULL::sparsevec)) t2;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP TABLE t;
|
||||||
12
test/sql/hnsw_sparsevec_l1.sql
Normal file
12
test/sql/hnsw_sparsevec_l1.sql
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
SET enable_seqscan = off;
|
||||||
|
|
||||||
|
CREATE TABLE t (val sparsevec(3));
|
||||||
|
INSERT INTO t (val) VALUES ('{}/3'), ('{1:1,2:2,3:3}/3'), ('{1:1,2:1,3:1}/3'), (NULL);
|
||||||
|
CREATE INDEX ON t USING hnsw (val sparsevec_l1_ops);
|
||||||
|
|
||||||
|
INSERT INTO t (val) VALUES ('{1:1,2:2,3:4}/3');
|
||||||
|
|
||||||
|
SELECT * FROM t ORDER BY val <+> '{1:3,2:3,3:3}/3';
|
||||||
|
SELECT COUNT(*) FROM (SELECT * FROM t ORDER BY val <+> (SELECT NULL::sparsevec)) t2;
|
||||||
|
|
||||||
|
DROP TABLE t;
|
||||||
@@ -67,8 +67,8 @@ for (1 .. 20)
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check each index type
|
# Check each index type
|
||||||
my @operators = ("<->", "<#>", "<=>");
|
my @operators = ("<->", "<#>", "<=>", "<+>");
|
||||||
my @opclasses = ("sparsevec_l2_ops", "sparsevec_ip_ops", "sparsevec_cosine_ops");
|
my @opclasses = ("sparsevec_l2_ops", "sparsevec_ip_ops", "sparsevec_cosine_ops", "sparsevec_l1_ops");
|
||||||
|
|
||||||
for my $i (0 .. $#operators)
|
for my $i (0 .. $#operators)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ for (1 .. 20)
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check each index type
|
# Check each index type
|
||||||
my @operators = ("<->", "<#>", "<=>");
|
my @operators = ("<->", "<#>", "<=>", "<+>");
|
||||||
my @opclasses = ("sparsevec_l2_ops", "sparsevec_ip_ops", "sparsevec_cosine_ops");
|
my @opclasses = ("sparsevec_l2_ops", "sparsevec_ip_ops", "sparsevec_cosine_ops", "sparsevec_l1_ops");
|
||||||
|
|
||||||
for my $i (0 .. $#operators)
|
for my $i (0 .. $#operators)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user