From 5e96e30a9a1ceac7ae3ab72d67c08c06c7c4ee4c Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sat, 26 Aug 2023 19:38:41 -0400 Subject: [PATCH 1/3] add test coverage for updating $vector --- package.json | 2 +- tests/driver/api.test.ts | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 90c509b..794450a 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "dotenv": "^16.0.1", "jsdoc-babel": "^0.5.0", "jsdoc-to-markdown": "^7.1.1", - "mongoose": "^7.4.0", + "mongoose": "git@github.com:Automattic/mongoose.git#vkarpov15/handle-top-level-dollar-keys", "nyc": "^15.1.0", "sinon": "15.2.0", "ts-mocha": "^10.0.0", diff --git a/tests/driver/api.test.ts b/tests/driver/api.test.ts index 215b4d7..4f786d3 100644 --- a/tests/driver/api.test.ts +++ b/tests/driver/api.test.ts @@ -846,27 +846,42 @@ describe(`Mongoose Model API level tests`, async () => { it('supports sort() with $meta with findOneAndUpdate()', async function() { const res = await Vector. - findOneAndUpdate({}, { name: 'found vector' }, { returnDocument: 'after' }). + findOneAndUpdate( + {}, + { name: 'found vector', $vector: [990, 1] }, + { returnDocument: 'before' } + ). sort({ $vector: { $meta: [99, 1] } }); assert.deepStrictEqual(res.$vector, [100, 1]); - assert.strictEqual(res.name, 'found vector'); + assert.strictEqual(res.name, 'Test vector 2'); + + const doc = await Vector.findById(res._id); + assert.strictEqual(doc.name, 'found vector'); + assert.deepStrictEqual(doc.$vector, [990, 1]); }); it('supports sort() with $meta with findOneAndReplace()', async function() { const res = await Vector. findOneAndReplace( {}, - { name: 'found vector' }, + { name: 'found vector', $vector: [990, 1] }, { returnDocument: 'before' } ). sort({ $vector: { $meta: [99, 1] } }); assert.deepStrictEqual(res.$vector, [100, 1]); assert.strictEqual(res.name, 'Test vector 2'); + + const doc = await Vector.findById(res._id); + assert.strictEqual(doc.name, 'found vector'); + assert.deepStrictEqual(doc.$vector, [990, 1]); }); it('supports sort() with $meta with findOneAndDelete()', async function() { const res = await Vector. - findOneAndDelete({}, { name: 'found vector' }, { returnDocument: 'before' }). + findOneAndDelete( + {}, + { returnDocument: 'before' } + ). sort({ $vector: { $meta: [1, 99] } }); assert.deepStrictEqual(res.$vector, [1, 100]); assert.strictEqual(res.name, 'Test vector 1'); From c5ad2c403ae451a0063424271b693d33cb82967d Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sun, 27 Aug 2023 21:54:37 -0400 Subject: [PATCH 2/3] add test cases covering $setOnInsert, $unset, save --- tests/driver/api.test.ts | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/driver/api.test.ts b/tests/driver/api.test.ts index 4f786d3..e4bc73e 100644 --- a/tests/driver/api.test.ts +++ b/tests/driver/api.test.ts @@ -809,6 +809,15 @@ describe(`Mongoose Model API level tests`, async () => { ]); }); + it('supports updating $vector with save()', async function() { + const vector = await Vector.findOne({ name: 'Test vector 1' }).orFail(); + vector.$vector = [1, 101]; + await vector.save(); + + const { $vector } = await Vector.findOne({ name: 'Test vector 1' }).orFail(); + assert.deepStrictEqual($vector, [1, 101]); + }); + it('supports sort() with $meta with find()', async function() { let res = await Vector. find({}). @@ -826,6 +835,13 @@ describe(`Mongoose Model API level tests`, async () => { sort({ $vector: { $meta: [99, 1] } }); assert.deepStrictEqual(res.map(doc => doc.name), ['Test vector 2', 'Test vector 1']); + res = await Vector. + find({}). + select({ $vector: 0 }). + sort({ $vector: { $meta: [99, 1] } }); + assert.deepStrictEqual(res.map(doc => doc.name), ['Test vector 2', 'Test vector 1']); + assert.deepStrictEqual(res.map(doc => doc.$vector), [undefined, undefined]); + await assert.rejects( Vector.find().limit(1001).sort({ $vector: { $meta: [99, 1] } }), /limit options should not be greater than 1000 for vector search/ @@ -842,6 +858,23 @@ describe(`Mongoose Model API level tests`, async () => { findOne({}). sort({ $vector: { $meta: [99, 1] } }); assert.deepStrictEqual(res.name, 'Test vector 2'); + + /*res = await Vector. + findOne({ $vector: [100, 1] }); + console.log(await Vector.find()); + assert.deepStrictEqual(res.name, 'Test vector 2');*/ + }); + + it('supports sort() with $meta with updateOne()', async function() { + await Vector. + updateOne( + {}, + { name: 'found vector', $vector: [990, 1] } + ). + sort({ $vector: { $meta: [99, 1] } }); + const vectors = await Vector.find().limit(20).sort({ name: 1 }); + assert.deepStrictEqual(vectors.map(v => v.name), ['Test vector 1', 'found vector']); + assert.deepStrictEqual(vectors.map(v => v.$vector), [[1, 100], [990, 1]]); }); it('supports sort() with $meta with findOneAndUpdate()', async function() { @@ -860,6 +893,37 @@ describe(`Mongoose Model API level tests`, async () => { assert.deepStrictEqual(doc.$vector, [990, 1]); }); + it('supports $setOnInsert of $vector with findOneAndUpdate()', async function() { + let res = await Vector. + findOneAndUpdate( + { name: 'Test vector 2' }, + { $setOnInsert: { $vector: [990, 1] } }, + { returnDocument: 'after', upsert: true } + ); + assert.deepStrictEqual(res.$vector, [100, 1]); + assert.strictEqual(res.name, 'Test vector 2'); + + res = await Vector. + findOneAndUpdate( + { name: 'Test vector 3' }, + { $setOnInsert: { $vector: [990, 1] } }, + { returnDocument: 'after', upsert: true } + ); + assert.deepStrictEqual(res.$vector, [990, 1]); + assert.strictEqual(res.name, 'Test vector 3'); + }); + + it('supports $unset of $vector with findOneAndUpdate()', async function() { + let res = await Vector. + findOneAndUpdate( + { name: 'Test vector 2' }, + { $unset: { $vector: 1 } }, + { returnDocument: 'after' } + ); + assert.deepStrictEqual(res.$vector, undefined); + assert.strictEqual(res.name, 'Test vector 2'); + }); + it('supports sort() with $meta with findOneAndReplace()', async function() { const res = await Vector. findOneAndReplace( From d4e78e1fdb796e99a905b340a3c327da6724a10c Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 30 Aug 2023 12:38:22 -0400 Subject: [PATCH 3/3] use Mongoose 7.5, support sort for updateOne --- package.json | 4 ++-- src/collections/collection.ts | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 794450a..6cd789c 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "dotenv": "^16.0.1", "jsdoc-babel": "^0.5.0", "jsdoc-to-markdown": "^7.1.1", - "mongoose": "git@github.com:Automattic/mongoose.git#vkarpov15/handle-top-level-dollar-keys", + "mongoose": "^7.5.0", "nyc": "^15.1.0", "sinon": "15.2.0", "ts-mocha": "^10.0.0", @@ -89,7 +89,7 @@ "winston": "^3.7.2" }, "peerDependencies": { - "mongoose": "^7.4.0" + "mongoose": "^7.5.0" }, "engines": { "node": ">=14.0.0" diff --git a/src/collections/collection.ts b/src/collections/collection.ts index 5646e6e..c43e019 100644 --- a/src/collections/collection.ts +++ b/src/collections/collection.ts @@ -107,13 +107,24 @@ export class Collection { async updateOne(filter: Record, update: Record, options?: UpdateOneOptions) { return executeOperation(async (): Promise => { - const command = { + type UpdateOneCommand = { + updateOne: { + filter?: Record, + sort?: SortOption, + update?: Record, + options?: UpdateOneOptions + } + } + const command: UpdateOneCommand = { updateOne: { filter, update, options } }; + if (options?.sort != null) { + command.updateOne.sort = options?.sort; + } setDefaultIdForUpsert(command.updateOne); const updateOneResp = await this.httpClient.executeCommand(command, updateOneInternalOptionsKeys); let resp = {