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

328

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

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

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

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

Ваш Ответ

8   ответов
104

https: //docs.mongodb.com/manual/reference/sql-comparison

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

MySQL

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

MongoDB

db.users.find({username:/Son/})
Ваш ответ MongoDB хорош; рассмотрите возможность редактирования вашего вопроса, чтобы удалить ненужный совет MySQL. maerics
Удалить все запросы или изменить их? Наиболее известный из SQL, это полезно для понимания MongoDB Zheng Kai
@ ZhengKai: на этом сайте вы, как правило, должны прямо отвечать на вопрос, используя только специальные технологии, помеченные и запрошенные. maerics
@ maerics лично Я считаю, что включение Чжэн в MySQL очень полезно, поскольку это дает точку отсчета. Mike Bartlett
Я также нашел ссылку на SQL релевантной, думаю, она должна остаться. vikingsteve
18

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

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

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

150

это вполне возможно.

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

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

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

Видеть:http: //www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpression

Пожалуйста, включите фрагмент кода, демонстрирующий использование регулярных выражений для поиска. Ответы должны содержать больше информации, чем просто ссылка ... maerics
как комментарии в выбранном ответе, я верюdb.users.findOne({"username" : /.*son.*/}); также может быть излишним, и регулярное выражение может быть просто/son/ Arthur Weborg
Выбранный ответ не сработал для меня, но этот сработал (я выполняю монго-запросы с помощью команд docker exec). Я думаю, что этот ответ должен быть выбранным, потому что он выглядит более универсальным. Arthur Weborg
Отредактируйте это, чтобы просто использовать{ username: /son/ } Wyck
ой ну спасибо! Пример кода только что добавлен. James Gan
60

текстовый индекс в поле (ах) для поиска и использования $ @ Тек оператор для запроса.

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

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

Затем, чтобы искать:

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

Контрольные отметки (~ 150 тыс. Документов):

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

Заметки

Коллекция может иметь только один текстовый индекс. Вы можете использовать подстановочный текстовый индекс, если вы хотите искатьлюбо строковое поле, вот так:db.collection.createIndex( { "$**": "text" } ). Текстовый индекс может быть большим. Он содержит одну запись указателя для каждого уникального слова после каждого элемента в каждом проиндексированном поле для каждого вставленного документа. Построение текстового индекса займет больше времени, чем обычного индекса. Текстовый указатель не хранит фразы или информацию о близости слов в документах. В результате запросы фраз будут выполняться намного эффективнее, когда вся коллекция помещается в ОЗУ.
no, оператор текстового ввода не позволяет выполнять «содержит», поэтому он будет возвращать только точное совпадение слов. Начиная с версии 3.0, в настоящее время единственным вариантом является использование регулярного выражения, то есть db.users.find ({имя пользователя: / son / i }) этот ищет каждого пользователя, содержащего «son» (без учета регистра) comeGetSome
Вам нужно переиндексировать, когда вы добавляете или удаляете документы в / из коллекции? Jake Wilson
15

если вы подключаете MongoDB через Python

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

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

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

Как игнорировать теги HTML в совпадении с RegExp:

var text = '<p>The <b>tiger</b> (<i>Panthera tigris</i>) is the largest <a href="/wiki/Felidae" title="Felidae">cat</a> <a href="/wiki/Species" title="Species">species</a>, most recognizable for its pattern of dark vertical stripes on reddish-orange fur with a lighter underside. The species is classified in the genus <i><a href="/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="/wiki/Lion" title="Lion">lion</a>, <a href="/wiki/Leopard" title="Leopard">leopard</a>, <a href="/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="/wiki/Deer" title="Deer">deer</a> and <a href="/wiki/Bovid" class="mw-redirect" title="Bovid">bovids</a>.</p>';
var searchString = 'largest cat species';

var rx = '';
searchString.split(' ').forEach(e => {
  rx += '('+e+')((?:\\s*(?:<\/?\\w[^<>]*>)?\\s*)*)';
});

rx = new RegExp(rx, 'igm');

console.log(text.match(rx));

Это, вероятно, очень легко превратить в агрегирующий фильтр MongoDB.

11

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

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

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

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

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

db.users.findOne({"username" : {$regex : ".*son.*"}});
@ Стенни, тогда что ты предлагаешь для эффективного использования индекса и поиска подстроки. Blue Sky
Могу попробовать полнотекстовый поиск в Mongo 2.6 wprl
@ Vish: если вы обычно используете произвольный текстовый поиск по полю и у вас есть большое количество документов, я бы разбил текст на части для более эффективных запросов. Вы могли бы использовать Multikeys для простого полнотекстового поиска, или, возможно, построить инвертированный индекс как отдельная коллекция. Для нечастых поисков или небольшой коллекции документов сканирование полного индекса может быть приемлемой (хотя и не оптимальной) производительностью. Stennie
Разве это не излишество? То, что вы хотите, этоdb.users.findOne({"username" : {$regex : "son"}}); JamieJag
Обратите внимание, что это будетн эффективно использовать индекс и в результате все значения будут проверяться на совпадения. Смотрите заметки наРегулярные выражени Stennie

Похожие вопросы