Монго, как найти поле, исключая специальные символы

У меня есть этот документ Mongo

{
    _id: ObjectId('6616851ed50d6d1451fa8176'),
  phone: "+7(926)458-54-52",
  name: "Aboba"
}

Я хочу найти этот документ, если пользователь вводит 7926, но мой фильтр фильтрует и другое поле.

Я фильтрую по регулярному выражению телефона или имени, но телефон содержит «+» и «()», поэтому, если пользовательский ввод равен 7926, он не будет найден.

Как я могу это решить?

Мое регулярное выражение:

{'$regex': f'\\w*{request_value}\\w*', '$options': 'i'}

Я фильтрую так:

{$or: [name: regex, phone: regex}
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете создать очищенную строку с именем phoneForSearch, сначала удалив все специальные символы. Затем используйте поиск по регулярному выражению на phoneForSearch.

db.collection.aggregate([
  {
    "$set": {
      "phoneForSearch": {
        "$reduce": {
          "input": {
            "$regexFindAll": {
              "input": "$phone",
              "regex": "\\d+"
            }
          },
          "initialValue": "",
          "in": {
            "$concat": [
              "$$value",
              "$$this.match"
            ]
          }
        }
      }
    }
  },
  {
    "$match": {
      $expr: {
        $or: [
          // phone search
          {
            $ne: [
              -1,
              {
                "$indexOfCP": [
                  "$phoneForSearch",
                  //user input here
                  "7926"
                ]
              }
            ]
          },
          // name search
          {
            "$regexMatch": {
              "input": "$name",
              // name regex here
              "regex": "^abo",
              "options": "i"
            }
          }
        ]
      }
    }
  }
])

Игровая площадка Монго


Рекомендуется «разбить» поле phone на отдельные поля, чтобы его было легче обрабатывать и форматировать следующим образом:

[
  {
    _id: ObjectId("6616851ed50d6d1451fa8176"),
    phone: {
      countryCode: "7",
      areaCode: "926",
      number: "4585452"
    },
    name: "Aboba"
  }
]

Игровая площадка Монго

\\w*{request_value}\\w* Итак, нет возможности не исключать специальные символы из этого регулярного выражения, да? Его можно дополнить дополнительными полями?
Zessshi 10.04.2024 15:21

+1 к созданию очищенного строкового поля. В вашей ситуации я бы использовал этот ответ. Создайте это поле для всех документов отдельно, а также для новых вставок и обновлений. А затем используйте для этого регулярное выражение.

aneroid 10.04.2024 15:56

Ответ анероида @Zessshi должен быть тем, который непосредственно касается вашего вопроса, и я рад, что это принятое решение. Я просто хочу подчеркнуть использование создания вспомогательного поля поиска (то есть очищенного phoneForSearch в моем ответе). Если вы часто выполняете такой поиск, вы можете рассмотреть возможность материализации поля (т. е. сохранить его в базе данных) и проиндексировать его. Таким образом, вы можете получить потенциальный выигрыш в производительности.

ray 10.04.2024 16:48
Ответ принят как подходящий

Во-первых, я согласен с ответом Рэя.

создайте очищенную строку с именем phoneForSearch

Это позволит вам также лучше индексировать и искать по нему.

Однако, если вы действительно хотите просто игнорировать специальные символы, вы можете сделать что-то вроде этого:

Для номеров телефонов отделяйте каждую цифру знаком \D*, который означает «одна или несколько нецифр». Сначала добавьте \D между всеми цифрами в вашем приложении/коде, а затем выполните поиск, используя его в качестве регулярного выражения. Таким образом, поиск 7926 по нечистому номеру телефона можно выполнить следующим образом:

db.collection.find({
  phone: {
    $regex: "\\D*7\\D*9\\D*2\\D*6\\D*",
    $options: "i"
  }
})

Это также соответствует другим нечисловым значениям, например:

+7(926)458-54-52
+7===+++|||9....2++++6458-54-52
+7ssss9xxxx2yyyy6dddd-458-54-52
+7===+++|||9....2++++6458-54-52

вот почему лучше НЕ делать что-то подобное. Игровая площадка Монго

И если вы хотите обработать эту вставку \D в Mongo, вы можете сделать это следующим образом:

(обновление)

Это все, что мне удалось сделать с вставкой \D в регулярное выражение поиска по телефону, но это не работает, когда шаблон регулярного выражения является именем поля: $regex: "$phone_search_regex". mongoplayground.net/p/RxZZPGYPM89

aneroid 10.04.2024 15:55

Другие вопросы по теме