Частичный текстовый поиск с индексами в MongoDB - PullRequest
0 голосов
/ 09 января 2019

У меня есть коллекция контактов с полями, именами, адресами электронной почты и номерами мобильных телефонов с примерно 2 миллионами записей (через некоторое время это может увеличиться до 10 миллионов). Я хочу выполнить поиск без учета регистра по полям имени и электронной почты с $regex при использовании индексов.

Я создал текстовые индексы для полей имени и электронной почты, но частичный поиск в этом случае не работает. Кроме того, я также пытался индексировать поля имени и адреса электронной почты и использовал оператор $regex с параметром без учета регистра, но в этом случае индексы не применяются к обоим этим полям.

Вот что я уже пробовал:

Пробовал: {'$text': { $search: searchstring }} Результат: Невозможно найти частичный текст

Пробовал: {'name': { $regex: 'searchstring', $options: 'i' }} Попробовал: {'email': { $regex: 'searchstring', $options: 'i' }} Результат: Возможность поиска по частичному тексту, но без использования индекса, поэтому поиск очень медленный, что соответствует цели

Так что в основном то, что мне нужно достичь в MongoDB, похоже на функцию подстановочного знака (%) в SQL Server с 1. Очень высокая скорость поиска (доли секунды) 2. Возможность частичного поиска.

Пример на SQL Server должен выглядеть следующим образом

select * from tblUsers where username like '%amit%'

Мы используем NodeJS для внутреннего интерфейса и React для внешнего интерфейса.

Вот индексы: [ { "v": 2, "ключ": { "_id": 1 }, "name": " id ", "нс": "контакты" }, { "v": 2, "ключ": { "companyId": 1,0, "isDeleted": 1,0, "_id": 1,0, "списки": 1,0 }, "name": "contacts_cmpId_isdel_id_lists", "нс": "контакты", "фон": правда }, { "v": 2, "ключ": { "companyId": 1,0, "isDeleted": 1,0, "_fts": "текст", "_ftsx": 1 }, "name": "contacts_cmpId_nm_em_mb_unq", "нс": "контакты", "фон": правда, "веса": { "адрес электронной почты": 1, «мобильный»: 1, «имя»: 1, "uniqueId": 1 }, "default_language": "english", "language_override": "language", "textIndexVersion": 3 }, { "v": 2, "ключ": { "companyId": 1,0, "isDeleted": 1,0, "адрес электронной почты": 1,0 }, "name": "companyId_1_isDeleted_1_emailAddress_1", "нс": "контакты", "сопоставление": { "locale": "en", caseLevel: false, caseFirst: off, «сила»: 2, "numericOrdering": ложь, «альтернативный»: «невосполнимый», "maxVariable": "пункт", «нормализация»: ложь, «назад»: ложно, "версия": "57.1" } }, { "v": 2, "ключ": { "companyId": 1, "isDeleted": 1, «имя»: 1, «списки»: 1, "createDate": 1 }, "name": "contacts_cmpId_isdel_name_lists_crdt", "нс": "контакты", "фон": правда } ]

Вот запрос объяснения

db.getCollection('contacts').find({companyId: ObjectId('5bfcd53c19ebe6727a000d90'), isDeleted: false, 'name': { $regex: 'test1User', $options: 'i' }}).skip(0).limit(100).explain('executionStats')

и его вывод:

"executeStats": { "executeSuccess": правда, "nReturned": 1, "executeTimeMillis": 3634, "totalKeysExamined": 613865, "totalDocsExamined": 613840,}

1 Ответ

0 голосов
/ 09 января 2019

Я предполагаю, что вы используете мангуст, так как он упоминается в тегах. Если это так, вы можете использовать регулярные выражения, как это

UserModel.find({name:new RegExp(nameVariable,"i")}); //"i" makes it case sensitive 

попробуйте это должно решить проблему

...