Skip to content

Commit

Permalink
fix(mongo): move $fulltext from $and to top level (#4066)
Browse files Browse the repository at this point in the history
Closes #4065

---------

Co-authored-by: Martin Adámek <banan23@gmail.com>
  • Loading branch information
funduck and B4nan committed Feb 26, 2023
1 parent 53a08ac commit 680a99c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
17 changes: 16 additions & 1 deletion packages/mongodb/src/MongoDriver.ts
Expand Up @@ -138,14 +138,29 @@ export class MongoDriver extends DatabaseDriver<MongoConnection> {

private renameFields<T>(entityName: string, data: T, where = false): T {
// copy to new variable to prevent changing the T type or doing as unknown casts
const copiedData: T & { $fulltext?: string; $text?: { $search: string } } = Object.assign({}, data); // copy first
const copiedData: Dictionary = Object.assign({}, data); // copy first
Utils.renameKey(copiedData, 'id', '_id');
const meta = this.metadata.find(entityName);

if (meta) {
this.inlineEmbeddables(meta, copiedData, where);
}

// If we had a query with $fulltext and some filter we end up with $and with $fulltext in it.
// We will try to move $fulltext to top level.
if (copiedData.$and) {
for (let i = 0; i < copiedData.$and.length; i++) {
const and = copiedData.$and[i];
if ('$fulltext' in and) {
if ('$fulltext' in copiedData) {
throw new Error('Cannot merge multiple $fulltext conditions to top level of the query object.');
}
copiedData.$fulltext = and.$fulltext!;
delete and.$fulltext;
}
}
}

// move search terms from data['$fulltext'] to mongo's structure: data['$text']['search']
if ('$fulltext' in copiedData) {
copiedData.$text = { $search: copiedData.$fulltext! };
Expand Down
29 changes: 29 additions & 0 deletions tests/issues/GH4065.test.ts
@@ -0,0 +1,29 @@
import { MikroORM } from '@mikro-orm/mongodb';

import { Author, Book } from '../entities';
import { closeReplSets, initORMMongo } from '../bootstrap';

describe('GH4065', () => {

let orm: MikroORM;

beforeAll(async () => orm = await initORMMongo(true));
beforeEach(async () => orm.schema.clearDatabase());

afterAll(async () => {
await orm.close();
await closeReplSets();
});

test('should load entities with $fulltext and filter set', async () => {
const god = new Author('God', 'hello@heaven.god');
const bible = new Book('Bible', god);
await orm.em.persistAndFlush(bible);
orm.em.clear();

const booksRepository = orm.em.getRepository(Book);
orm.em.addFilter('BreakFulltext', { title: { $re: '.*' } }, Book, true);
const books = await booksRepository.find({ $fulltext: 'Bible' });
expect(books.length).toBe(1);
});
});

0 comments on commit 680a99c

Please sign in to comment.