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

View File

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

View File

@@ -1,7 +1,7 @@
import { strict as assert } from 'assert';
import testUtils, { GLOBAL } from '../test-utils';
import { transformArguments } from './CREATE';
import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages } from '.';
import { SchemaFieldTypes, SchemaTextFieldPhonetics, RedisSearchLanguages, VectorAlgorithms } from '.';
describe('CREATE', () => {
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', () => {
it('with AS', () => {
assert.deepEqual(

View File

@@ -2,10 +2,32 @@ import { strict as assert } from 'assert';
import { transformArguments } from './EXPLAIN';
describe('EXPLAIN', () => {
it('transformArguments', () => {
describe('transformArguments', () => {
it('simple', () => {
assert.deepEqual(
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 function transformArguments(index: string, query: string): Array<string> {
return ['FT.EXPLAIN', index, query];
interface ExplainOptions {
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;

View File

@@ -15,32 +15,56 @@ describe('INFO', () => {
await client.ft.create('index', {
field: SchemaFieldTypes.TEXT
});
assert.deepEqual(
await client.ft.info('index'),
{
indexName: 'index',
indexOptions: [],
indexDefinition: {
defaultScore: '1',
keyType: 'HASH',
prefixes: ['']
indexDefinition: Object.create(null, {
default_score: {
value: '1',
configurable: true,
enumerable: true
},
attributes: [[
'identifier',
'field',
'attribute',
'field',
'type',
'TEXT',
'WEIGHT',
'1'
]],
key_type: {
value: 'HASH',
configurable: true,
enumerable: true
},
prefixes: {
value: [''],
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',
maxDocId: '0',
numTerms: '0',
numRecords: '0',
invertedSzMb: '0',
vectorIndexSzMb: '0',
totalInvertedIndexBlocks: '0',
offsetVectorsSzMb: '0',
docTableSizeMb: '0',
@@ -67,7 +91,8 @@ describe('INFO', () => {
globalTotal: 0,
indexCapacity: 128,
idnexTotal: 0
}
},
stopWords: undefined
}
);
}, 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> {
return ['FT.INFO', index];
}
type InfoRawReply = [
_: string,
indexName: string,
_: string,
indexOptions: Array<string>,
_: string,
indexDefinition: [
_: string,
keyType: string,
_: string,
prefixes: Array<string>,
_: string,
defaultScore: string
'index_name',
RedisCommandArgument,
'index_options',
Array<RedisCommandArgument>,
'index_definition',
Array<RedisCommandArgument>,
'attributes',
Array<Array<RedisCommandArgument>>,
'num_docs',
RedisCommandArgument,
'max_doc_id',
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,
attributes: Array<Array<string>>,
_: string,
numDocs: string,
_: string,
maxDocId: string,
_: string,
numTerms: string,
_: string,
numRecords: string,
_: 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
'cursor_stats',
[
'global_idle',
number,
'global_total',
number,
'index_capacity',
number,
'index_total',
number
],
_: string,
cursorStats: [
_: string,
globalIdle: number,
_: string,
globalTotal: number,
_: string,
indexCapacity: number,
_: string,
idnexTotal: number
]
'stopwords_list'?,
Array<RedisCommandArgument>?
];
interface InfoReply {
indexName: string;
indexOptions: Array<string>;
indexDefinition: {
keyType: string;
prefixes: Array<string>;
defaultScore: string;
};
attributes: Array<Array<string>>;
numDocs: string;
maxDocId: string;
numTerms: string;
numRecords: string;
invertedSzMb: string;
totalInvertedIndexBlocks: string;
offsetVectorsSzMb: string;
docTableSizeMb: string;
sortableValuesSizeMb: string;
keyTableSizeMb: string;
recordsPerDocAvg: string;
bytesPerRecordAvg: string;
offsetsPerTermAvg: string;
offsetBitsPerRecordAvg: string;
hashIndexingFailures: string;
indexing: string;
percentIndexed: string;
indexName: RedisCommandArgument;
indexOptions: Array<RedisCommandArgument>;
indexDefinition: Record<string, RedisCommandArgument>;
attributes: Array<Record<string, RedisCommandArgument>>;
numDocs: RedisCommandArgument;
maxDocId: RedisCommandArgument;
numTerms: RedisCommandArgument;
numRecords: RedisCommandArgument;
invertedSzMb: RedisCommandArgument;
vectorIndexSzMb: RedisCommandArgument;
totalInvertedIndexBlocks: RedisCommandArgument;
offsetVectorsSzMb: RedisCommandArgument;
docTableSizeMb: RedisCommandArgument;
sortableValuesSizeMb: RedisCommandArgument;
keyTableSizeMb: RedisCommandArgument;
recordsPerDocAvg: RedisCommandArgument;
bytesPerRecordAvg: RedisCommandArgument;
offsetsPerTermAvg: RedisCommandArgument;
offsetBitsPerRecordAvg: RedisCommandArgument;
hashIndexingFailures: RedisCommandArgument;
indexing: RedisCommandArgument;
percentIndexed: RedisCommandArgument;
gcStats: {
bytesCollected: string;
totalMsRun: string;
totalCycles: string;
averageCycleTimeMs: string;
lastRunTimeMs: string;
gcNumericTreesMissed: string;
gcBlocksDenied: string;
bytesCollected: RedisCommandArgument;
totalMsRun: RedisCommandArgument;
totalCycles: RedisCommandArgument;
averageCycleTimeMs: RedisCommandArgument;
lastRunTimeMs: RedisCommandArgument;
gcNumericTreesMissed: RedisCommandArgument;
gcBlocksDenied: RedisCommandArgument;
};
cursorStats: {
globalIdle: number;
@@ -123,49 +120,49 @@ interface InfoReply {
indexCapacity: number;
idnexTotal: number;
};
stopWords: Array<RedisCommandArgument> | undefined;
}
export function transformReply(rawReply: InfoRawReply): InfoReply {
console.log(rawReply);
return {
indexName: rawReply[1],
indexOptions: rawReply[3],
indexDefinition: {
keyType: rawReply[5][1],
prefixes: rawReply[5][3],
defaultScore: rawReply[5][5]
},
attributes: rawReply[7],
indexDefinition: transformTuplesReply(rawReply[5]),
attributes: rawReply[7].map(attribute => transformTuplesReply(attribute)),
numDocs: rawReply[9],
maxDocId: rawReply[11],
numTerms: rawReply[13],
numRecords: rawReply[15],
invertedSzMb: rawReply[17],
totalInvertedIndexBlocks: rawReply[19],
offsetVectorsSzMb: rawReply[21],
docTableSizeMb: rawReply[23],
sortableValuesSizeMb: rawReply[25],
keyTableSizeMb: rawReply[27],
recordsPerDocAvg: rawReply[29],
bytesPerRecordAvg: rawReply[31],
offsetsPerTermAvg: rawReply[33],
offsetBitsPerRecordAvg: rawReply[35],
hashIndexingFailures: rawReply[37],
indexing: rawReply[39],
percentIndexed: rawReply[41],
vectorIndexSzMb: rawReply[19],
totalInvertedIndexBlocks: rawReply[21],
offsetVectorsSzMb: rawReply[23],
docTableSizeMb: rawReply[25],
sortableValuesSizeMb: rawReply[27],
keyTableSizeMb: rawReply[29],
recordsPerDocAvg: rawReply[31],
bytesPerRecordAvg: rawReply[33],
offsetsPerTermAvg: rawReply[35],
offsetBitsPerRecordAvg: rawReply[37],
hashIndexingFailures: rawReply[39],
indexing: rawReply[41],
percentIndexed: rawReply[43],
gcStats: {
bytesCollected: rawReply[43][1],
totalMsRun: rawReply[43][3],
totalCycles: rawReply[43][5],
averageCycleTimeMs: rawReply[43][7],
lastRunTimeMs: rawReply[43][9],
gcNumericTreesMissed: rawReply[43][11],
gcBlocksDenied: rawReply[43][13]
bytesCollected: rawReply[45][1],
totalMsRun: rawReply[45][3],
totalCycles: rawReply[45][5],
averageCycleTimeMs: rawReply[45][7],
lastRunTimeMs: rawReply[45][9],
gcNumericTreesMissed: rawReply[45][11],
gcBlocksDenied: rawReply[45][13]
},
cursorStats: {
globalIdle: rawReply[45][1],
globalTotal: rawReply[45][3],
indexCapacity: rawReply[45][5],
idnexTotal: rawReply[45][7]
}
globalIdle: rawReply[47][1],
globalTotal: rawReply[47][3],
indexCapacity: rawReply[47][5],
idnexTotal: rawReply[47][7]
},
stopWords: rawReply[49]
};
}

View File

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

View File

@@ -213,9 +213,30 @@ describe('SEARCH', () => {
['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']
);
});
testUtils.testWithClient('client.ft.search', async client => {
it('with DIALECT', () => {
assert.deepEqual(
transformArguments('index', 'query', {
DIALECT: 1
}),
['FT.SEARCH', 'index', 'query', 'DIALECT', '1']
);
});
});
describe('client.ft.search', () => {
testUtils.testWithClient('DIALECT 1', async client => {
await Promise.all([
client.ft.create('index', {
field: SchemaFieldTypes.NUMERIC
@@ -224,7 +245,9 @@ describe('SEARCH', () => {
]);
assert.deepEqual(
await client.ft.search('index', '*'),
await client.ft.search('index', '*', {
DIALECT: 1
}),
{
total: 1,
documents: [{
@@ -240,4 +263,48 @@ describe('SEARCH', () => {
}
);
}, 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 { 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;
@@ -54,6 +54,8 @@ export interface SearchOptions {
from: number | string;
size: number | string;
};
PARAMS?: Params;
DIALECT?: number;
}
export function transformArguments(
@@ -61,9 +63,10 @@ export function transformArguments(
query: string,
options?: SearchOptions
): RedisCommandArguments {
const args: RedisCommandArguments = ['FT.SEARCH', index, query];
pushSearchOptions(args, options);
return args;
return pushSearchOptions(
['FT.SEARCH', index, query],
options
);
}
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 => {

View File

@@ -6,6 +6,7 @@ interface SpellCheckTerms {
interface SpellCheckOptions {
DISTANCE?: number;
TERMS?: SpellCheckTerms | Array<SpellCheckTerms>;
DIALECT?: number;
}
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;
}

View File

@@ -28,7 +28,7 @@ import * as SUGLEN from './SUGLEN';
import * as SYNDUMP from './SYNDUMP';
import * as SYNUPDATE from './SYNUPDATE';
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 { SearchOptions } from './SEARCH';
@@ -172,15 +172,28 @@ export enum SchemaFieldTypes {
TEXT = 'TEXT',
NUMERIC = 'NUMERIC',
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;
AS?: string;
} & E);
type CreateSchemaCommonField<
T extends SchemaFieldTypes,
E = Record<string, never>
> = CreateSchemaField<
T,
({
SORTABLE?: true | 'UNF';
NOINDEX?: true;
} & E);
} & E)
>;
export enum SchemaTextFieldPhonetics {
DM_EN = 'dm:en',
@@ -189,27 +202,55 @@ export enum SchemaTextFieldPhonetics {
DM_ES = 'dm:es'
}
type CreateSchemaTextField = CreateSchemaField<SchemaFieldTypes.TEXT, {
type CreateSchemaTextField = CreateSchemaCommonField<SchemaFieldTypes.TEXT, {
NOSTEM?: true;
WEIGHT?: number;
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;
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 {
[field: string]:
CreateSchemaTextField |
CreateSchemaNumericField |
CreateSchemaGeoField |
CreateSchemaTagField;
CreateSchemaTagField |
CreateSchemaFlatVectorField |
CreateSchemaHNSWVectorField;
}
export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema) {
@@ -257,6 +298,47 @@ export function pushSchema(args: RedisCommandArguments, schema: RediSearchSchema
}
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) {
@@ -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(
args: RedisCommandArguments,
options?: SearchOptions
): RedisCommandArguments {
if (options?.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;
}

View File

@@ -1,5 +1,5 @@
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 { SearchOptions } from './commands/SEARCH';

View File

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