В моей MongoDb около 500 миллионов документов, которые выглядят следующим образом:
{
"_id": objectId,
"Name": "John Smith",
"Address": "132, My Street, Kingston, New York 12401"
}
Теперь я хочу запросить данные на основе регулярного выражения имени и регулярного выражения адреса, поскольку иногда имя в моей базе данных чувствительно к регистру, а иногда и адрес. Я попытался создать отдельный индекс (1) для обоих полей, также попытался создать составной индекс с текстом (в текстовом индексе проблема в том, что он ищет только в том случае, если текстовый индекс находился в одном поле, либо адрес, либо имя не работает с индексом обоих полей. с текстом).
Также попробовал индексировать оба поля как: createIndex({Name: 1, Address: 1}); <--- это возвращает данные также, если я ищу только по одному полю. Я хочу выполнить запрос типа:
var name = "john smith";
var address = "new york";
var userData = await db
.collection("userData")
.find({
$and: [
{ Name: { $regex: new RegExp(name, "i") } },
{ Address: { $regex: new RegExp(address, "i") } },
],
})
.skip(skip)
.limit(limitNumber)
.toArray();
Если я попробую использовать один индекс, я все равно смогу выполнить запрос с одним полем, а не с обоими полями. Я попробовал оба поля со всеми вышеперечисленными методами, загрузка занимает целую вечность, даже если я попытался расширить время запроса, мс все равно ничего не возвращает или даже ошибку.
Спасибо
Попробуй это:
var userData = await db
.collection("userData")
.find({
Name: { $regex: name, $options: "i" },
Address: { $regex: address, $options: "i" }
})
$and
оператор не нужен.
Если вам нравится его использовать, то вы должны использовать его с $expr
var userData = await db
.collection("userData")
.find({ $expr: {
$and: [
{ $regexMatch: { input: "$Name", regex: name, options: "i" } },
{ $regexMatch: { input: "$Address", regex: address, options: "i" } }
],
}})
Так какой индекс для этого нужен? {Имя: 1, Адрес: 1}? Спасибо
@JahanzaibKhan: индексы не помогут в запросах такого рода. (вроде как. Полное сканирование индекса, вероятно, все же лучше, чем полное сканирование коллекции, но оно все равно будет намного медленнее, чем запрос на равенство или диапазон)
Он не использует индекс. Этот ответ только делает ваш запрос рабочим.
``` var userData = await db .collection("userData") .find({ Name: { $regex: name, $options: "i" }, Address: { $regex: адрес, $options: "i" } }) ``` Уже пробовал, не помогло. и попробовал второй тоже, но ничего не получил.
@WernfriedDomscheit ничего не возвращает. он возвращается только тогда, когда я ищу регулярное выражение в одном поле, независимо от того, какой индекс я делаю или нет!.
я только что попробовал: .find({ $or: [ { Name: { $regex: new RegExp(name, "i") } }, { Address: { $regex: new RegExp(address, "i") } }, ], }) он вернул несколько совпадающих имени и адреса, но также вернул другие, совпадающие с именем или адресом.
Итак, я тестировал все больше и больше и выяснил, что если у меня нет составного индекса для поля имени и адреса вместе, запрос занимает 500 секунд, в противном случае это займет 85 секунд, если я запрашиваю регулярное выражение в обоих полях. Всем спасибо.
составной индекс с порядком возрастания, текст не требуется.
Wrt-индексы для поиска по регулярным выражениям без учета регистра: «Индексы без учета регистра обычно не повышают производительность запросов
$regex
. Реализация$regex
не учитывает параметры сортировки и не может эффективно использовать индексы без учета регистра».