1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-07 13:22:56 +03:00

Support Vector Similarity (#1785)

* ft.alter

* support paramas

* remove only and skip

* merge

* fix imports

* add Vector field

* update version

* push attributes

* typo

* test

* version check

* remove .only

* remove unued import

* add support for DIALECT

* clean code

Co-authored-by: Avital-Fine <avital.fine@redis.com>
Co-authored-by: leibale <leibale1998@gmail.com>
This commit is contained in:
Avital Fine
2022-03-31 13:13:06 +02:00
committed by GitHub
parent 33a3f3f6c6
commit 4683e969b8
16 changed files with 631 additions and 304 deletions

180
package-lock.json generated
View File

@@ -978,14 +978,14 @@
"dev": true "dev": true
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
"integrity": "sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==", "integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/type-utils": "5.16.0", "@typescript-eslint/type-utils": "5.17.0",
"@typescript-eslint/utils": "5.16.0", "@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8", "ignore": "^5.1.8",
@@ -1026,14 +1026,14 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz",
"integrity": "sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==", "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.16.0", "@typescript-eslint/typescript-estree": "5.17.0",
"debug": "^4.3.2" "debug": "^4.3.2"
}, },
"engines": { "engines": {
@@ -1053,13 +1053,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz",
"integrity": "sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==", "integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.16.0" "@typescript-eslint/visitor-keys": "5.17.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1070,12 +1070,12 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz",
"integrity": "sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==", "integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/utils": "5.16.0", "@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@@ -1096,9 +1096,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz",
"integrity": "sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==", "integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1109,13 +1109,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz",
"integrity": "sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==", "integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.16.0", "@typescript-eslint/visitor-keys": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"globby": "^11.0.4", "globby": "^11.0.4",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@@ -1180,15 +1180,15 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==", "integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.16.0", "@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
}, },
@@ -1204,12 +1204,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz",
"integrity": "sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==", "integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"eslint-visitor-keys": "^3.0.0" "eslint-visitor-keys": "^3.0.0"
}, },
"engines": { "engines": {
@@ -1695,9 +1695,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001320", "version": "1.0.30001322",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz",
"integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", "integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -2155,9 +2155,9 @@
"dev": true "dev": true
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.96", "version": "1.4.101",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.96.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.101.tgz",
"integrity": "sha512-DPNjvNGPabv6FcyjzLAN4C0psN/GgD9rSGvMTuv81SeXG/EX3mCz0wiw9N1tUEnfQXYCJi3H8M0oFPRziZh7rw==", "integrity": "sha512-XJH+XmJjACx1S7ASl/b//KePcda5ocPnFH2jErztXcIS8LpP0SE6rX8ZxiY5/RaDPnaF1rj0fPaHfppzb0e2Aw==",
"dev": true "dev": true
}, },
"node_modules/email-addresses": { "node_modules/email-addresses": {
@@ -7533,14 +7533,14 @@
"dev": true "dev": true
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.17.0.tgz",
"integrity": "sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==", "integrity": "sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/type-utils": "5.16.0", "@typescript-eslint/type-utils": "5.17.0",
"@typescript-eslint/utils": "5.16.0", "@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8", "ignore": "^5.1.8",
@@ -7561,52 +7561,52 @@
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.17.0.tgz",
"integrity": "sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==", "integrity": "sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.16.0", "@typescript-eslint/typescript-estree": "5.17.0",
"debug": "^4.3.2" "debug": "^4.3.2"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.17.0.tgz",
"integrity": "sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==", "integrity": "sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.16.0" "@typescript-eslint/visitor-keys": "5.17.0"
} }
}, },
"@typescript-eslint/type-utils": { "@typescript-eslint/type-utils": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.17.0.tgz",
"integrity": "sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==", "integrity": "sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/utils": "5.16.0", "@typescript-eslint/utils": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.17.0.tgz",
"integrity": "sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==", "integrity": "sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.17.0.tgz",
"integrity": "sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==", "integrity": "sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/visitor-keys": "5.16.0", "@typescript-eslint/visitor-keys": "5.17.0",
"debug": "^4.3.2", "debug": "^4.3.2",
"globby": "^11.0.4", "globby": "^11.0.4",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@@ -7646,26 +7646,26 @@
} }
}, },
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.17.0.tgz",
"integrity": "sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==", "integrity": "sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.16.0", "@typescript-eslint/scope-manager": "5.17.0",
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"@typescript-eslint/typescript-estree": "5.16.0", "@typescript-eslint/typescript-estree": "5.17.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.16.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.16.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.17.0.tgz",
"integrity": "sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==", "integrity": "sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.16.0", "@typescript-eslint/types": "5.17.0",
"eslint-visitor-keys": "^3.0.0" "eslint-visitor-keys": "^3.0.0"
} }
}, },
@@ -8011,9 +8011,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001320", "version": "1.0.30001322",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz",
"integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", "integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==",
"dev": true "dev": true
}, },
"chalk": { "chalk": {
@@ -8353,9 +8353,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.4.96", "version": "1.4.101",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.96.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.101.tgz",
"integrity": "sha512-DPNjvNGPabv6FcyjzLAN4C0psN/GgD9rSGvMTuv81SeXG/EX3mCz0wiw9N1tUEnfQXYCJi3H8M0oFPRziZh7rw==", "integrity": "sha512-XJH+XmJjACx1S7ASl/b//KePcda5ocPnFH2jErztXcIS8LpP0SE6rX8ZxiY5/RaDPnaF1rj0fPaHfppzb0e2Aw==",
"dev": true "dev": true
}, },
"email-addresses": { "email-addresses": {

View File

@@ -434,6 +434,26 @@ describe('AGGREGATE', () => {
); );
}); });
}); });
it('with PARAMS', () => {
assert.deepEqual(
transformArguments('index', '*', {
PARAMS: {
param: 'value'
}
}),
['FT.AGGREGATE', 'index', '*', 'PARAMS', '2', 'param', 'value']
);
});
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', '*', {
DIALECT: 1
}),
['FT.AGGREGATE', 'index', '*', 'DIALECT', '1']
);
});
}); });
testUtils.testWithClient('client.ft.aggregate', async client => { testUtils.testWithClient('client.ft.aggregate', async client => {

View File

@@ -1,6 +1,6 @@
import { RedisCommandArgument, RedisCommandArguments } from '@node-redis/client/dist/lib/commands'; import { RedisCommandArgument, RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
import { pushVerdictArgument, transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers'; import { pushVerdictArgument, transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers';
import { PropertyName, pushArgumentsWithLength, pushSortByArguments, SortByProperty } from '.'; import { Params, PropertyName, pushArgumentsWithLength, pushParamsArgs, pushSortByArguments, SortByProperty } from '.';
export enum AggregateSteps { export enum AggregateSteps {
GROUPBY = 'GROUPBY', GROUPBY = 'GROUPBY',
@@ -122,6 +122,8 @@ export interface AggregateOptions {
VERBATIM?: true; VERBATIM?: true;
LOAD?: LoadField | Array<LoadField>; LOAD?: LoadField | Array<LoadField>;
STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>; STEPS?: Array<GroupByStep | SortStep | ApplyStep | LimitStep | FilterStep>;
PARAMS?: Params;
DIALECT?: number;
} }
export function transformArguments( export function transformArguments(
@@ -129,17 +131,16 @@ export function transformArguments(
query: string, query: string,
options?: AggregateOptions options?: AggregateOptions
): RedisCommandArguments { ): RedisCommandArguments {
return pushAggregatehOptions(
const args = ['FT.AGGREGATE', index, query]; ['FT.AGGREGATE', index, query],
pushAggregatehOptions(args, options); options
return args; );
} }
export function pushAggregatehOptions( export function pushAggregatehOptions(
args: RedisCommandArguments, args: RedisCommandArguments,
options?: AggregateOptions options?: AggregateOptions
): RedisCommandArguments { ): RedisCommandArguments {
if (options?.VERBATIM) { if (options?.VERBATIM) {
args.push('VERBATIM'); args.push('VERBATIM');
} }
@@ -202,6 +203,12 @@ export function pushAggregatehOptions(
} }
} }
pushParamsArgs(args, options?.PARAMS);
if (options?.DIALECT) {
args.push('DIALECT', options.DIALECT.toString());
}
return args; return args;
} }
@@ -257,7 +264,6 @@ function pushGroupByReducer(args: RedisCommandArguments, reducer: GroupByReducer
} }
} }
}); });
break; break;
} }

View File

@@ -1,7 +1,7 @@
import { strict as assert } from 'assert'; import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils'; import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CREATE'; import { transformArguments } from './CREATE';
import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages } from '.'; import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages, VectorAlgorithms } from '.';
describe('CREATE', () => { describe('CREATE', () => {
describe('transformArguments', () => { describe('transformArguments', () => {
@@ -126,6 +126,52 @@ describe('CREATE', () => {
}); });
}); });
describe('VECTOR', () => {
it('Flat algorithm', () => {
assert.deepEqual(
transformArguments('index', {
field: {
type: SchemaFieldTypes.VECTOR,
ALGORITHM: VectorAlgorithms.FLAT,
TYPE: 'FLOAT32',
DIM: 2,
DISTANCE_METRIC: 'L2',
INITIAL_CAP: 1000000,
BLOCK_SIZE: 1000
}
}),
[
'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'FLAT', '10', 'TYPE',
'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'INITIAL_CAP', '1000000',
'BLOCK_SIZE', '1000'
]
);
});
it('HNSW algorithm', () => {
assert.deepEqual(
transformArguments('index', {
field: {
type: SchemaFieldTypes.VECTOR,
ALGORITHM: VectorAlgorithms.HNSW,
TYPE: 'FLOAT32',
DIM: 2,
DISTANCE_METRIC: 'L2',
INITIAL_CAP: 1000000,
M: 40,
EF_CONSTRUCTION: 250,
EF_RUNTIME: 20
}
}),
[
'FT.CREATE', 'index', 'SCHEMA', 'field', 'VECTOR', 'HNSW', '14', 'TYPE',
'FLOAT32', 'DIM', '2', 'DISTANCE_METRIC', 'L2', 'INITIAL_CAP', '1000000',
'M', '40', 'EF_CONSTRUCTION', '250', 'EF_RUNTIME', '20'
]
);
});
});
describe('with generic options', () => { describe('with generic options', () => {
it('with AS', () => { it('with AS', () => {
assert.deepEqual( assert.deepEqual(

View File

@@ -2,10 +2,32 @@ import { strict as assert } from 'assert';
import { transformArguments } from './EXPLAIN'; import { transformArguments } from './EXPLAIN';
describe('EXPLAIN', () => { describe('EXPLAIN', () => {
it('transformArguments', () => { describe('transformArguments', () => {
assert.deepEqual( it('simple', () => {
transformArguments('index', '*'), assert.deepEqual(
['FT.EXPLAIN', 'index', '*'] transformArguments('index', '*'),
); ['FT.EXPLAIN', 'index', '*']
);
});
it('with PARAMS', () => {
assert.deepEqual(
transformArguments('index', '*', {
PARAMS: {
param: 'value'
}
}),
['FT.EXPLAIN', 'index', '*', 'PARAMS', '2', 'param', 'value']
);
});
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', '*', {
DIALECT: 1
}),
['FT.EXPLAIN', 'index', '*', 'DIALECT', '1']
);
});
}); });
}); });

View File

@@ -1,7 +1,26 @@
import { Params, pushParamsArgs } from ".";
export const IS_READ_ONLY = true; export const IS_READ_ONLY = true;
export function transformArguments(index: string, query: string): Array<string> { interface ExplainOptions {
return ['FT.EXPLAIN', index, query]; PARAMS?: Params;
DIALECT?: number;
}
export function transformArguments(
index: string,
query: string,
options?: ExplainOptions
): Array<string> {
const args = ['FT.EXPLAIN', index, query];
pushParamsArgs(args, options?.PARAMS);
if (options?.DIALECT) {
args.push('DIALECT', options.DIALECT.toString());
}
return args;
} }
export declare function transformReply(): string; export declare function transformReply(): string;

View File

@@ -15,32 +15,56 @@ describe('INFO', () => {
await client.ft.create('index', { await client.ft.create('index', {
field: SchemaFieldTypes.TEXT field: SchemaFieldTypes.TEXT
}); });
assert.deepEqual( assert.deepEqual(
await client.ft.info('index'), await client.ft.info('index'),
{ {
indexName: 'index', indexName: 'index',
indexOptions: [], indexOptions: [],
indexDefinition: { indexDefinition: Object.create(null, {
defaultScore: '1', default_score: {
keyType: 'HASH', value: '1',
prefixes: [''] configurable: true,
}, enumerable: true
attributes: [[ },
'identifier', key_type: {
'field', value: 'HASH',
'attribute', configurable: true,
'field', enumerable: true
'type', },
'TEXT', prefixes: {
'WEIGHT', value: [''],
'1' configurable: true,
]], enumerable: true
}
}),
attributes: [Object.create(null, {
identifier: {
value: 'field',
configurable: true,
enumerable: true
},
attribute: {
value: 'field',
configurable: true,
enumerable: true
},
type: {
value: 'TEXT',
configurable: true,
enumerable: true
},
WEIGHT: {
value: '1',
configurable: true,
enumerable: true
}
})],
numDocs: '0', numDocs: '0',
maxDocId: '0', maxDocId: '0',
numTerms: '0', numTerms: '0',
numRecords: '0', numRecords: '0',
invertedSzMb: '0', invertedSzMb: '0',
vectorIndexSzMb: '0',
totalInvertedIndexBlocks: '0', totalInvertedIndexBlocks: '0',
offsetVectorsSzMb: '0', offsetVectorsSzMb: '0',
docTableSizeMb: '0', docTableSizeMb: '0',
@@ -67,7 +91,8 @@ describe('INFO', () => {
globalTotal: 0, globalTotal: 0,
indexCapacity: 128, indexCapacity: 128,
idnexTotal: 0 idnexTotal: 0
} },
stopWords: undefined
} }
); );
}, GLOBAL.SERVERS.OPEN); }, GLOBAL.SERVERS.OPEN);

View File

@@ -1,121 +1,118 @@
import { RedisCommandArgument } from '@node-redis/client/dist/lib/commands';
import { transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers';
export function transformArguments(index: string): Array<string> { export function transformArguments(index: string): Array<string> {
return ['FT.INFO', index]; return ['FT.INFO', index];
} }
type InfoRawReply = [ type InfoRawReply = [
_: string, 'index_name',
indexName: string, RedisCommandArgument,
_: string, 'index_options',
indexOptions: Array<string>, Array<RedisCommandArgument>,
_: string, 'index_definition',
indexDefinition: [ Array<RedisCommandArgument>,
_: string, 'attributes',
keyType: string, Array<Array<RedisCommandArgument>>,
_: string, 'num_docs',
prefixes: Array<string>, RedisCommandArgument,
_: string, 'max_doc_id',
defaultScore: string RedisCommandArgument,
'num_terms',
RedisCommandArgument,
'num_records',
RedisCommandArgument,
'inverted_sz_mb',
RedisCommandArgument,
'vector_index_sz_mb',
RedisCommandArgument,
'total_inverted_index_blocks',
RedisCommandArgument,
'offset_vectors_sz_mb',
RedisCommandArgument,
'doc_table_size_mb',
RedisCommandArgument,
'sortable_values_size_mb',
RedisCommandArgument,
'key_table_size_mb',
RedisCommandArgument,
'records_per_doc_avg',
RedisCommandArgument,
'bytes_per_record_avg',
RedisCommandArgument,
'offsets_per_term_avg',
RedisCommandArgument,
'offset_bits_per_record_avg',
RedisCommandArgument,
'hash_indexing_failures',
RedisCommandArgument,
'indexing',
RedisCommandArgument,
'percent_indexed',
RedisCommandArgument,
'gc_stats',
[
'bytes_collected',
RedisCommandArgument,
'total_ms_run',
RedisCommandArgument,
'total_cycles',
RedisCommandArgument,
'average_cycle_time_ms',
RedisCommandArgument,
'last_run_time_ms',
RedisCommandArgument,
'gc_numeric_trees_missed',
RedisCommandArgument,
'gc_blocks_denied',
RedisCommandArgument
], ],
_: string, 'cursor_stats',
attributes: Array<Array<string>>, [
_: string, 'global_idle',
numDocs: string, number,
_: string, 'global_total',
maxDocId: string, number,
_: string, 'index_capacity',
numTerms: string, number,
_: string, 'index_total',
numRecords: string, number
_: string,
invertedSzMb: string,
_: string,
totalInvertedIndexBlocks: string,
_: string,
offsetVectorsSzMb: string,
_: string,
docTableSizeMb: string,
_: string,
sortableValuesSizeMb: string,
_: string,
keyTableSizeMb: string,
_: string,
recordsPerDocAvg: string,
_: string,
bytesPerRecordAvg: string,
_: string,
offsetsPerTermAvg: string,
_: string,
offsetBitsPerRecordAvg: string,
_: string,
hashIndexingFailures: string,
_: string,
indexing: string,
_: string,
percentIndexed: string,
_: string,
gcStats: [
_: string,
bytesCollected: string,
_: string,
totalMsRun: string,
_: string,
totalCycles: string,
_: string,
averageCycleTimeMs: string,
_: string,
lastRunTimeMs: string,
_: string,
gcNumericTreesMissed: string,
_: string,
gcBlocksDenied: string
], ],
_: string, 'stopwords_list'?,
cursorStats: [ Array<RedisCommandArgument>?
_: string,
globalIdle: number,
_: string,
globalTotal: number,
_: string,
indexCapacity: number,
_: string,
idnexTotal: number
]
]; ];
interface InfoReply { interface InfoReply {
indexName: string; indexName: RedisCommandArgument;
indexOptions: Array<string>; indexOptions: Array<RedisCommandArgument>;
indexDefinition: { indexDefinition: Record<string, RedisCommandArgument>;
keyType: string; attributes: Array<Record<string, RedisCommandArgument>>;
prefixes: Array<string>; numDocs: RedisCommandArgument;
defaultScore: string; maxDocId: RedisCommandArgument;
}; numTerms: RedisCommandArgument;
attributes: Array<Array<string>>; numRecords: RedisCommandArgument;
numDocs: string; invertedSzMb: RedisCommandArgument;
maxDocId: string; vectorIndexSzMb: RedisCommandArgument;
numTerms: string; totalInvertedIndexBlocks: RedisCommandArgument;
numRecords: string; offsetVectorsSzMb: RedisCommandArgument;
invertedSzMb: string; docTableSizeMb: RedisCommandArgument;
totalInvertedIndexBlocks: string; sortableValuesSizeMb: RedisCommandArgument;
offsetVectorsSzMb: string; keyTableSizeMb: RedisCommandArgument;
docTableSizeMb: string; recordsPerDocAvg: RedisCommandArgument;
sortableValuesSizeMb: string; bytesPerRecordAvg: RedisCommandArgument;
keyTableSizeMb: string; offsetsPerTermAvg: RedisCommandArgument;
recordsPerDocAvg: string; offsetBitsPerRecordAvg: RedisCommandArgument;
bytesPerRecordAvg: string; hashIndexingFailures: RedisCommandArgument;
offsetsPerTermAvg: string; indexing: RedisCommandArgument;
offsetBitsPerRecordAvg: string; percentIndexed: RedisCommandArgument;
hashIndexingFailures: string;
indexing: string;
percentIndexed: string;
gcStats: { gcStats: {
bytesCollected: string; bytesCollected: RedisCommandArgument;
totalMsRun: string; totalMsRun: RedisCommandArgument;
totalCycles: string; totalCycles: RedisCommandArgument;
averageCycleTimeMs: string; averageCycleTimeMs: RedisCommandArgument;
lastRunTimeMs: string; lastRunTimeMs: RedisCommandArgument;
gcNumericTreesMissed: string; gcNumericTreesMissed: RedisCommandArgument;
gcBlocksDenied: string; gcBlocksDenied: RedisCommandArgument;
}; };
cursorStats: { cursorStats: {
globalIdle: number; globalIdle: number;
@@ -123,49 +120,49 @@ interface InfoReply {
indexCapacity: number; indexCapacity: number;
idnexTotal: number; idnexTotal: number;
}; };
stopWords: Array<RedisCommandArgument> | undefined;
} }
export function transformReply(rawReply: InfoRawReply): InfoReply { export function transformReply(rawReply: InfoRawReply): InfoReply {
console.log(rawReply);
return { return {
indexName: rawReply[1], indexName: rawReply[1],
indexOptions: rawReply[3], indexOptions: rawReply[3],
indexDefinition: { indexDefinition: transformTuplesReply(rawReply[5]),
keyType: rawReply[5][1], attributes: rawReply[7].map(attribute => transformTuplesReply(attribute)),
prefixes: rawReply[5][3],
defaultScore: rawReply[5][5]
},
attributes: rawReply[7],
numDocs: rawReply[9], numDocs: rawReply[9],
maxDocId: rawReply[11], maxDocId: rawReply[11],
numTerms: rawReply[13], numTerms: rawReply[13],
numRecords: rawReply[15], numRecords: rawReply[15],
invertedSzMb: rawReply[17], invertedSzMb: rawReply[17],
totalInvertedIndexBlocks: rawReply[19], vectorIndexSzMb: rawReply[19],
offsetVectorsSzMb: rawReply[21], totalInvertedIndexBlocks: rawReply[21],
docTableSizeMb: rawReply[23], offsetVectorsSzMb: rawReply[23],
sortableValuesSizeMb: rawReply[25], docTableSizeMb: rawReply[25],
keyTableSizeMb: rawReply[27], sortableValuesSizeMb: rawReply[27],
recordsPerDocAvg: rawReply[29], keyTableSizeMb: rawReply[29],
bytesPerRecordAvg: rawReply[31], recordsPerDocAvg: rawReply[31],
offsetsPerTermAvg: rawReply[33], bytesPerRecordAvg: rawReply[33],
offsetBitsPerRecordAvg: rawReply[35], offsetsPerTermAvg: rawReply[35],
hashIndexingFailures: rawReply[37], offsetBitsPerRecordAvg: rawReply[37],
indexing: rawReply[39], hashIndexingFailures: rawReply[39],
percentIndexed: rawReply[41], indexing: rawReply[41],
percentIndexed: rawReply[43],
gcStats: { gcStats: {
bytesCollected: rawReply[43][1], bytesCollected: rawReply[45][1],
totalMsRun: rawReply[43][3], totalMsRun: rawReply[45][3],
totalCycles: rawReply[43][5], totalCycles: rawReply[45][5],
averageCycleTimeMs: rawReply[43][7], averageCycleTimeMs: rawReply[45][7],
lastRunTimeMs: rawReply[43][9], lastRunTimeMs: rawReply[45][9],
gcNumericTreesMissed: rawReply[43][11], gcNumericTreesMissed: rawReply[45][11],
gcBlocksDenied: rawReply[43][13] gcBlocksDenied: rawReply[45][13]
}, },
cursorStats: { cursorStats: {
globalIdle: rawReply[45][1], globalIdle: rawReply[47][1],
globalTotal: rawReply[45][3], globalTotal: rawReply[47][3],
indexCapacity: rawReply[45][5], indexCapacity: rawReply[47][5],
idnexTotal: rawReply[45][7] idnexTotal: rawReply[47][7]
} },
stopWords: rawReply[49]
}; };
} }

View File

@@ -1,5 +1,6 @@
import { SearchOptions, SearchRawReply, transformReply as transformSearchReply } from './SEARCH'; import { SearchOptions, SearchRawReply, transformReply as transformSearchReply } from './SEARCH';
import { pushSearchOptions, ProfileOptions, ProfileRawReply, ProfileReply, transformProfile } from '.'; import { pushSearchOptions, ProfileOptions, ProfileRawReply, ProfileReply, transformProfile } from '.';
import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
export const IS_READ_ONLY = true; export const IS_READ_ONLY = true;
@@ -7,7 +8,7 @@ export function transformArguments(
index: string, index: string,
query: string, query: string,
options?: ProfileOptions & SearchOptions options?: ProfileOptions & SearchOptions
): Array<string> { ): RedisCommandArguments {
const args = ['FT.PROFILE', index, 'SEARCH']; const args = ['FT.PROFILE', index, 'SEARCH'];
if (options?.LIMITED) { if (options?.LIMITED) {
@@ -15,8 +16,7 @@ export function transformArguments(
} }
args.push('QUERY', query); args.push('QUERY', query);
pushSearchOptions(args, options) return pushSearchOptions(args, options);
return args;
} }
type ProfileSearchRawReply = ProfileRawReply<SearchRawReply>; type ProfileSearchRawReply = ProfileRawReply<SearchRawReply>;

View File

@@ -213,31 +213,98 @@ describe('SEARCH', () => {
['FT.SEARCH', 'index', 'query', 'LIMIT', '0', '1'] ['FT.SEARCH', 'index', 'query', 'LIMIT', '0', '1']
); );
}); });
it('with PARAMS', () => {
assert.deepEqual(
transformArguments('index', 'query', {
PARAMS: {
param: 'value'
}
}),
['FT.SEARCH', 'index', 'query', 'PARAMS', '2', 'param', 'value']
);
});
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', 'query', {
DIALECT: 1
}),
['FT.SEARCH', 'index', 'query', 'DIALECT', '1']
);
});
}); });
testUtils.testWithClient('client.ft.search', async client => { describe('client.ft.search', () => {
await Promise.all([ testUtils.testWithClient('DIALECT 1', async client => {
client.ft.create('index', { await Promise.all([
field: SchemaFieldTypes.NUMERIC client.ft.create('index', {
}), field: SchemaFieldTypes.NUMERIC
client.hSet('1', 'field', '1') }),
]); client.hSet('1', 'field', '1')
]);
assert.deepEqual( assert.deepEqual(
await client.ft.search('index', '*'), await client.ft.search('index', '*', {
{ DIALECT: 1
total: 1, }),
documents: [{ {
id: '1', total: 1,
value: Object.create(null, { documents: [{
field: { id: '1',
value: '1', value: Object.create(null, {
configurable: true, field: {
enumerable: true value: '1',
} configurable: true,
}) enumerable: true
}] }
} })
); }]
}, GLOBAL.SERVERS.OPEN); }
);
}, GLOBAL.SERVERS.OPEN);
testUtils.testWithClient('DIALECT 2', async client => {
await Promise.all([
client.ft.create('index', {
field: SchemaFieldTypes.NUMERIC
}),
client.hSet('1', 'field', '1'),
client.hSet('2', 'field', '2'),
client.hSet('3', 'field', '3')
]);
assert.deepEqual(
await client.ft.search('index', '@field:[$min $max]', {
PARAMS: {
min: 1,
max: 2
},
DIALECT: 2
}),
{
total: 2,
documents: [{
id: '1',
value: Object.create(null, {
field: {
value: '1',
configurable: true,
enumerable: true
}
})
}, {
id: '2',
value: Object.create(null, {
field: {
value: '2',
configurable: true,
enumerable: true
}
})
}]
}
);
}, GLOBAL.SERVERS.OPEN);
});
}); });

View File

@@ -1,6 +1,6 @@
import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands'; import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
import { transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers'; import { transformTuplesReply } from '@node-redis/client/dist/lib/commands/generic-transformers';
import { pushSearchOptions, RedisSearchLanguages, PropertyName, SortByProperty, SearchReply } from '.'; import { pushSearchOptions, RedisSearchLanguages, Params, PropertyName, SortByProperty, SearchReply } from '.';
export const FIRST_KEY_INDEX = 1; export const FIRST_KEY_INDEX = 1;
@@ -54,6 +54,8 @@ export interface SearchOptions {
from: number | string; from: number | string;
size: number | string; size: number | string;
}; };
PARAMS?: Params;
DIALECT?: number;
} }
export function transformArguments( export function transformArguments(
@@ -61,9 +63,10 @@ export function transformArguments(
query: string, query: string,
options?: SearchOptions options?: SearchOptions
): RedisCommandArguments { ): RedisCommandArguments {
const args: RedisCommandArguments = ['FT.SEARCH', index, query]; return pushSearchOptions(
pushSearchOptions(args, options); ['FT.SEARCH', index, query],
return args; options
);
} }
export type SearchRawReply = Array<any>; export type SearchRawReply = Array<any>;

View File

@@ -47,6 +47,15 @@ describe('SPELLCHECK', () => {
); );
}); });
}); });
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', 'query', {
DIALECT: 1
}),
['FT.SPELLCHECK', 'index', 'query', 'DIALECT', '1']
);
});
}); });
testUtils.testWithClient('client.ft.spellCheck', async client => { testUtils.testWithClient('client.ft.spellCheck', async client => {

View File

@@ -6,6 +6,7 @@ interface SpellCheckTerms {
interface SpellCheckOptions { interface SpellCheckOptions {
DISTANCE?: number; DISTANCE?: number;
TERMS?: SpellCheckTerms | Array<SpellCheckTerms>; TERMS?: SpellCheckTerms | Array<SpellCheckTerms>;
DIALECT?: number;
} }
export function transformArguments(index: string, query: string, options?: SpellCheckOptions): Array<string> { export function transformArguments(index: string, query: string, options?: SpellCheckOptions): Array<string> {
@@ -25,6 +26,10 @@ export function transformArguments(index: string, query: string, options?: Spell
} }
} }
if (options?.DIALECT) {
args.push('DIALECT', options.DIALECT.toString());
}
return args; return args;
} }

View File

@@ -28,7 +28,7 @@ import * as SUGLEN from './SUGLEN';
import * as SYNDUMP from './SYNDUMP'; import * as SYNDUMP from './SYNDUMP';
import * as SYNUPDATE from './SYNUPDATE'; import * as SYNUPDATE from './SYNUPDATE';
import * as TAGVALS from './TAGVALS'; import * as TAGVALS from './TAGVALS';
import { RedisCommandArguments } from '@node-redis/client/dist/lib/commands'; import { RedisCommandArgument, RedisCommandArguments } from '@node-redis/client/dist/lib/commands';
import { pushOptionalVerdictArgument, pushVerdictArgument } from '@node-redis/client/dist/lib/commands/generic-transformers'; import { pushOptionalVerdictArgument, pushVerdictArgument } from '@node-redis/client/dist/lib/commands/generic-transformers';
import { SearchOptions } from './SEARCH'; import { SearchOptions } from './SEARCH';
@@ -172,16 +172,29 @@ export enum SchemaFieldTypes {
TEXT = 'TEXT', TEXT = 'TEXT',
NUMERIC = 'NUMERIC', NUMERIC = 'NUMERIC',
GEO = 'GEO', GEO = 'GEO',
TAG = 'TAG' TAG = 'TAG',
VECTOR = 'VECTOR'
} }
type CreateSchemaField<T extends SchemaFieldTypes, E = Record<keyof any, any>> = T | ({ type CreateSchemaField<
T extends SchemaFieldTypes,
E = Record<keyof any, any>
> = T | ({
type: T; type: T;
AS?: string; AS?: string;
SORTABLE?: true | 'UNF';
NOINDEX?: true;
} & E); } & E);
type CreateSchemaCommonField<
T extends SchemaFieldTypes,
E = Record<string, never>
> = CreateSchemaField<
T,
({
SORTABLE?: true | 'UNF';
NOINDEX?: true;
} & E)
>;
export enum SchemaTextFieldPhonetics { export enum SchemaTextFieldPhonetics {
DM_EN = 'dm:en', DM_EN = 'dm:en',
DM_FR = 'dm:fr', DM_FR = 'dm:fr',
@@ -189,27 +202,55 @@ export enum SchemaTextFieldPhonetics {
DM_ES = 'dm:es' DM_ES = 'dm:es'
} }
type CreateSchemaTextField = CreateSchemaField<SchemaFieldTypes.TEXT, { type CreateSchemaTextField = CreateSchemaCommonField<SchemaFieldTypes.TEXT, {
NOSTEM?: true; NOSTEM?: true;
WEIGHT?: number; WEIGHT?: number;
PHONETIC?: SchemaTextFieldPhonetics; PHONETIC?: SchemaTextFieldPhonetics;
}>; }>;
type CreateSchemaNumericField = CreateSchemaField<SchemaFieldTypes.NUMERIC>; type CreateSchemaNumericField = CreateSchemaCommonField<SchemaFieldTypes.NUMERIC>;
type CreateSchemaGeoField = CreateSchemaField<SchemaFieldTypes.GEO>; type CreateSchemaGeoField = CreateSchemaCommonField<SchemaFieldTypes.GEO>;
type CreateSchemaTagField = CreateSchemaField<SchemaFieldTypes.TAG, { type CreateSchemaTagField = CreateSchemaCommonField<SchemaFieldTypes.TAG, {
SEPARATOR?: string; SEPARATOR?: string;
CASESENSITIVE?: true; CASESENSITIVE?: true;
}>; }>;
export enum VectorAlgorithms {
FLAT = 'FLAT',
HNSW = 'HNSW'
}
type CreateSchemaVectorField<
T extends VectorAlgorithms,
A extends Record<string, unknown>
> = CreateSchemaField<SchemaFieldTypes.VECTOR, {
ALGORITHM: T;
TYPE: string;
DIM: number;
DISTANCE_METRIC: 'L2' | 'IP' | 'COSINE';
INITIAL_CAP?: number;
} & A>;
type CreateSchemaFlatVectorField = CreateSchemaVectorField<VectorAlgorithms.FLAT, {
BLOCK_SIZE?: number;
}>;
type CreateSchemaHNSWVectorField = CreateSchemaVectorField<VectorAlgorithms.HNSW, {
M?: number;
EF_CONSTRUCTION?: number;
EF_RUNTIME?: number;
}>;
export interface RediSearchSchema { export interface RediSearchSchema {
[field: string]: [field: string]:
CreateSchemaTextField | CreateSchemaTextField |
CreateSchemaNumericField | CreateSchemaNumericField |
CreateSchemaGeoField | CreateSchemaGeoField |
CreateSchemaTagField; CreateSchemaTagField |
CreateSchemaFlatVectorField |
CreateSchemaHNSWVectorField;
} }
export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema) { export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema) {
@@ -257,6 +298,47 @@ export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema
} }
break; break;
case SchemaFieldTypes.VECTOR:
args.push(fieldOptions.ALGORITHM);
pushArgumentsWithLength(args, () => {
args.push(
'TYPE', fieldOptions.TYPE,
'DIM', fieldOptions.DIM.toString(),
'DISTANCE_METRIC', fieldOptions.DISTANCE_METRIC
);
if (fieldOptions.INITIAL_CAP) {
args.push('INITIAL_CAP', fieldOptions.INITIAL_CAP.toString());
}
switch (fieldOptions.ALGORITHM) {
case VectorAlgorithms.FLAT:
if (fieldOptions.BLOCK_SIZE) {
args.push('BLOCK_SIZE', fieldOptions.BLOCK_SIZE.toString());
}
break;
case VectorAlgorithms.HNSW:
if (fieldOptions.M) {
args.push('M', fieldOptions.M.toString());
}
if (fieldOptions.EF_CONSTRUCTION) {
args.push('EF_CONSTRUCTION', fieldOptions.EF_CONSTRUCTION.toString());
}
if (fieldOptions.EF_RUNTIME) {
args.push('EF_RUNTIME', fieldOptions.EF_RUNTIME.toString());
}
break;
}
});
continue; // vector fields do not contain SORTABLE and NOINDEX options
} }
if (fieldOptions.SORTABLE) { if (fieldOptions.SORTABLE) {
@@ -273,11 +355,27 @@ export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema
} }
} }
export type Params = Record<string, RedisCommandArgument | number>;
export function pushParamsArgs(
args: RedisCommandArguments,
params?: Params
): RedisCommandArguments {
if (params) {
const enrties = Object.entries(params);
args.push('PARAMS', (enrties.length * 2).toString());
for (const [key, value] of enrties) {
args.push(key, value.toString());
}
}
return args;
}
export function pushSearchOptions( export function pushSearchOptions(
args: RedisCommandArguments, args: RedisCommandArguments,
options?: SearchOptions options?: SearchOptions
): RedisCommandArguments { ): RedisCommandArguments {
if (options?.VERBATIM) { if (options?.VERBATIM) {
args.push('VERBATIM'); args.push('VERBATIM');
} }
@@ -381,6 +479,16 @@ export function pushSearchOptions(
); );
} }
if (options?.PARAMS) {
pushParamsArgs(args, options.PARAMS);
}
if (options?.DIALECT) {
args.push('DIALECT', options.DIALECT.toString());
}
console.log('!@#', args);
return args; return args;
} }

View File

@@ -1,5 +1,5 @@
export { default } from './commands'; export { default } from './commands';
export { RediSearchSchema, SchemaFieldTypes, SchemaTextFieldPhonetics, SearchReply } from './commands'; export { RediSearchSchema, SchemaFieldTypes, SchemaTextFieldPhonetics, SearchReply, VectorAlgorithms } from './commands';
export { AggregateSteps, AggregateGroupByReducers } from './commands/AGGREGATE'; export { AggregateSteps, AggregateGroupByReducers } from './commands/AGGREGATE';
export { SearchOptions } from './commands/SEARCH'; export { SearchOptions } from './commands/SEARCH';

View File

@@ -4,7 +4,7 @@ import RediSearch from '.';
export default new TestUtils({ export default new TestUtils({
dockerImageName: 'redislabs/redisearch', dockerImageName: 'redislabs/redisearch',
dockerImageVersionArgument: 'redisearch-version', dockerImageVersionArgument: 'redisearch-version',
defaultDockerVersion: '2.2.7' defaultDockerVersion: '2.4.3'
}); });
export const GLOBAL = { export const GLOBAL = {