Проверка, содержит ли поле строку

214

Я ищу оператора, который позволяет проверить, если значение поля содержит определенную строку.

Что-то вроде:

db.users.findOne({$contains:{"username":"son"}})

Это возможно?

Теги:

7 ответов

351
Лучший ответ

Вы можете сделать это со следующим кодом.

db.users.findOne({"username" : {$regex : ".*son.*"}});
  • 11
    Обратите внимание, что это не приведет к эффективному использованию индекса и приведет к тому, что все значения будут проверяться на совпадения. Смотрите примечания по регулярным выражениям
  • 6
    @ Стенни, тогда что вы предлагаете для эффективного использования индекса и поиска подстроки.
Показать ещё 12 комментариев
114

Как поддержка регулярного выражения оболочки Mongo, это вполне возможно.

db.users.findOne({"username" : /.*son.*/});

Если мы хотим, чтобы запрос был нечувствительным к регистру, мы можем использовать опцию "i", как показано ниже:

db.users.findOne({"username" : /.*son.*/i});

Смотрите: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions

  • 1
    Пожалуйста, включите фрагмент кода, демонстрирующий использование регулярных выражений для поиска. Ответы должны включать больше информации, чем просто ссылка ...
  • 1
    ООО Спасибо! Пример кода только что добавлен.
Показать ещё 4 комментария
75

http://www.mongodb.org/display/DOCS/SQL+to+Mongo+Mapping+Chart

http://php.net/manual/en/mongo.sqltomongo.php

MySQL

SELECT * FROM users WHERE username LIKE "%Son%"

MongoDB

db.users.find({username:/Son/})
  • 5
    Ваш ответ MongoDB хорош; рассмотрите возможность редактирования вашего вопроса, чтобы удалить ненужный совет MySQL.
  • 16
    Удалить весь запрос или изменить его? большинство людей знает SQL, это полезно для понимания MongoDB
Показать ещё 3 комментария
38

Начиная с версии 2.4 вы можете создать текстовый индекс в поле для поиска и использования $текстовый для запросов.

Сначала создайте индекс:

db.users.createIndex( { "username": "text" } )

Затем для поиска:

db.users.find( { $text: { $search: "son" } } )

Контрольные показатели (документы ~ 150K):

  • Regex (другие ответы) = > 5.6-6.9 секунд
  • Поиск текста = > .164-.201 секунд

Примечания:

  • Коллекция может иметь только один текстовый индекс. Вы можете использовать индекс подстановочного текста, если хотите найти любое строковое поле, например: db.collection.createIndex( { "$**": "text" } ).
  • Текстовый индекс может быть большим. Он содержит одну запись индекса для каждого уникального слова post-stemmed в каждом индексированном поле для каждого вставленного документа.
  • Текстовый индекс займет больше времени, чем обычный индекс.
  • Текстовый индекс не хранит фразы или информацию о близости слов в документах. В результате фразовые запросы будут выполняться намного эффективнее, если вся коллекция будет в ОЗУ.
  • 9
    нет, оператор текстового ввода не позволяет выполнять «содержит», поэтому он будет возвращать только точное совпадение слов. Начиная с версии 3.0, в настоящее время единственным вариантом является использование регулярных выражений, т.е. ) этот ищет каждого пользователя, содержащего «сын» (без учета регистра)
  • 1
    Нужно ли переиндексировать при добавлении или удалении документов в / из коллекции?
9

Вот что вам нужно сделать, если вы подключаете MongoDB через Python

db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})

вы также можете использовать имя переменной вместо "Сын" и, следовательно, конкатенацию строк.

  • 0
    в es2015 вы можете использовать обратные ссылки {$ regex:. .*${value}.* }
7

Поскольку это одно из первых хитов в поисковых системах, и ни одно из вышеизложенных, похоже, не работает для MongoDB 3.x, вот один регулярный поиск, который работает:

db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )

Не нужно создавать и добавлять индекс или аналогично.

0

Самый простой способ выполнить эту задачу.

Если вы хотите, чтобы запрос был чувствительным к регистру

db.getCollection("users").find({'username':/Son/})

Если вы хотите, чтобы запрос был без учета регистра

db.getCollection("users").find({'username':/Son/i})

Ещё вопросы

Сообщество Overcoder
Наверх
Меню