2012-05-15 2 views

ответ

382

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

db.users.findOne({"username" : {$regex : ".*son.*"}}); 
+9

Обратите внимание, что это ** не ** эффективно использует индекс и приводит к сканированию всех значений для совпадений. См. Примечания к [Регулярные выражения] (http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions) – Stennie

+3

@Stennie, то что вы предлагаете эффективно использовать индекс и найти подстроку , –

+3

@Vish: если ваш обычный вариант использования - это поиск в свободном тексте поля, и у вас есть большое количество документов, я бы подделал текст для более эффективных запросов. Вы можете использовать [multikeys] (http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo) для простого полнотекстового поиска или, возможно, создать [инвертированный индекс] (http: //en.wikipedia.org/wiki/Inverted_index) в виде отдельной коллекции. Для редких поисков или небольшого набора документов сканирование полного индекса может быть приемлемым (хотя и не оптимальным). – Stennie

121

As Mongo оболочка поддержка regex, это вполне возможно.

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

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

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

См: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions

+1

Пожалуйста, включите фрагмент кода, демонстрирующий использование регулярных выражений для поиска. Ответы должны содержать больше информации, чем просто ссылку ... – maerics

+0

О, спасибо! Образец кода просто добавлен. –

+1

Выбранный ответ не сработал для меня, но это было сделано (я выполняю запросы mongo с помощью команд docker exec). Я думаю, что это должен быть выбранный ответ, потому что он выглядит более универсальным. –

83

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/}) 
+3

Ваш ответ MongoDB хорош; рассмотрите возможность редактирования вопроса, чтобы удалить ненужный совет MySQL. – maerics

+8

Удалить все запрос или изменить его? большинство poeple известных SQL, полезно для понимания MongoDB –

+1

@ZhengKai: на этом сайте вы должны, как правило, отвечать на вопрос напрямую, используя только те технологии, которые были отмечены тегами и запрошены. – maerics

11

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

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

вы можете также использовать имя переменной вместо и, следовательно, конкатенации «Son».

+0

в es2015 вы можете использовать обратные ссылки {$ regex: '. * $ {Value}. *'} –

45

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

Во-первых, создать индекс:

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

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

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

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

  • Regex (другие ответы) => 5,6-6,9 секунд
  • Text Search => .164-0,201 секунд

Примечания:

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

no, оперативный текстовый оператор не разрешает выполнять «содержит», поэтому он возвращает только точное совпадение слов, единственный вариант в настоящее время, начиная с версии 3.0, используется regex, т. е. db.users.find ({имя_пользователя:/son/i)), этот поиск каждого пользователя, содержащего «сын» (case-insenstive) – comeGetSome

+0

Вам нужно переиндексировать при добавлении или удалении документы в/из коллекции? –

8

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

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

Нет необходимо создать и дополнительный индекс или аналогичный.

3

Простейший способ выполнить эту задачу

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

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

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

db.getCollection("users").find({'username':/Son/i}) 
Смежные вопросы