LINUX.ORG.RU

mongodb with «like»

 ,


0

1

Является ли $regex аналогом like ? Если да, то как, например, проверить то, что value содержит какое-либо значение из списка ? Есть список возможных значений object.value, нужно проверить, содержит(не эквивалентно) ли value хотя бы что-то из этого списка.


Возможно не угадал, но лучше прикрутить какой-нибудь индексирующую вундервафлю, например, solr.

anonymous
()
Ответ на: комментарий от anonymous

Соль, как понимаю, в том, что монго такого не предусматривает, либо я дебил(вероятнее всего). Т.е. для того, чтобы сравнить с каждым элементом из списка, содержащего n элементов, нужно прописать n регекспов в запросе. Но, возможно, реализация вменяемого запроса есть, а я его найти не смог.

Samu
() автор топика

1. Для списков надо использовать $in, $all, etc

2. Like/$regex не работает для списков

Ref.:

http://docs.mongodb.org/manual/reference/sql-comparison/

http://docs.mongodb.org/manual/reference/operator/regex/

И даже если бы такую фичу запилят, она будет в десятки раз тормозней, чем любой другой поиск. Можно написать свою функцию, которая будет join'ить списковые значения, а потом делать поиск по регепсу.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard
Для списков надо использовать $in, $all, etc

Но мне нужно contains, а не equals.

Можно написать свою функцию
Думаю, что кроме этого вариантов больше нет. Хотелось бы реализовать так, чтобы работало по возможности быстро и некостыльно, но $regex для каждого элемента списка — это не ок же !? Интересно бы было узнать решение у тех, кто такую проблему решал для каких-то крупных проектов.

Samu
() автор топика
Ответ на: комментарий от Samu

Но мне нужно contains, а не equals.

$in делает сверку по contains + 100% matching.

Интересно бы было узнать решение у тех, кто такую проблему решал для каких-то крупных проектов.

Только не здесь. Задавай вопрос на stackoverflow/stackexchange/forum.mongodb.org. Вообще, твоя задача означает неправильный подход к решению задачи. Регепсы на «крупных» проектах означают завал по производительности. ИМХО.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard
 Вообще, твоя задача означает неправильный подход к решению задачи. 

Полностью согласен, сформулировал, как смог. Конечно, это не обязательно должны быть регекспы, но и свою функцию писать тоже не вариант, если все можно сделать средствами одной только монго и это, думаю, будет намного рациональнее.

Samu
() автор топика
Ответ на: комментарий от gh0stwizard

У меня поле в базе не является списком, это строка. Ее нужно сравнивать (как in, а не как ==) с каждой строкой в некотором списке, если я правильно Вас понял.

Samu
() автор топика
Ответ на: комментарий от Samu

Конечно, это не обязательно должны быть регекспы, но и свою функцию писать тоже не вариант, если все можно сделать средствами одной только монго и это, думаю, будет намного рациональнее.

Вкратце, регепсы в монге это фича для тех, кто не осилил иную архитектуру для своего приложения. Рекспы в монге не могут использовать индексы (то, что сказано, что якобы /^a/ - ищет как по индексу сильно упрощено). В результате будут тормоза на больших коллекциях, а без ^ в начале даст еще больше тормозов.

Написать функцию несложно, т.к. случай тривиален. Другое дело, что если коллекция реально огромная, то есть смысл вообще отказать от затеи. Либо, предварительно делать отсев значений по другому полю. При этом полученный массив потенциальных документов должен стремится к нулю :) Если значений будет более тысячи, а таких запросов будет сотни тысяч, то также стоит еще раз подумать над отказом от сей затеи. В остальных случаях, пишем функцию (порядка 10-30 строк) и все.

Вывод функции можно оптимизировать, если кэшировать результаты поиска.

Но лучше пересмотреть архитектуру коллекций, документов и т.п. и постараться забыть про регепсы в монге.

Есть альтернатива, делать поиск по регепсам на стороне клиента. Порой это лучшее решение.

Для «некрупных» проектов регепсы отлично справляются.

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от Samu
{'id': 'Qwerty\n1,2,3,4\n__qwerty__\n' ...}
l = ['Asdfgh', '_zxcvbn_', '1,2,3,4']

В этом случае id будет удовлетворять нужному запросу.

Samu
() автор топика
Ответ на: комментарий от gh0stwizard

Коллекция не маленькая, несколько миллионов документов.

делать поиск по регепсам на стороне клиент
Тоже думал об этом, но это медленно, имхо.

Samu
() автор топика
Ответ на: комментарий от Samu

У меня поле в базе не является списком, это строка. Ее нужно сравнивать (как in, а не как ==) с каждой строкой в некотором списке, если я правильно Вас понял.

Что за регепс-то? Что за строка? Давайте конкретнее.

gh0stwizard ★★★★★
()
Ответ на: комментарий от Samu

smth должно содержать какой-либо элемент из l_1 _или_ из l_2, например.

Samu
() автор топика
Ответ на: комментарий от Samu

Ну и в чем проблема?

> db.re.insert({name:'Blah-blah-blah...\nVasya\n...blah-blah-blah...\n4 6 7\n...'});
> db.re.insert({name:'Blah-blah-blah...\nVanya\n...blah-blah-blah...\n7 3 6\n...'});
> db.re.find({name:{$regex:'(7 3 6)|(4 6 7)', $options: 'm'}});
{ "_id" : ObjectId("52507cf421fd1c54a43a0473"), "name" : "Blah-blah-blah...\nVasya\n...blah-blah-blah...\n4 6 7\n..." }
{ "_id" : ObjectId("52507d0121fd1c54a43a0474"), "name" : "Blah-blah-blah...\nVanya\n...blah-blah-blah...\n7 3 6\n..." }
gh0stwizard ★★★★★
()
Ответ на: комментарий от Samu

В смысле? Куда уж быстрее. В смысле можно ускорить, если в запрос добавить поле с точным значением. Поле должно быть проиндексированно.

gh0stwizard ★★★★★
()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от Samu

Могу ошибаться, но если память не изменят, то Oracle DB умеет строить индексы под регепсы, для ускорения поиска. Для монго можно сделать костыль в виде запуска запроса на нескольких серверах mongod. Коллекции можно разбить через шардинг. Но я точно не знаю, каков там прирост (если вообще есть) в таком случае.

gh0stwizard ★★★★★
()
Ответ на: комментарий от Samu

Еще как вариант, можно замаппить ключевые слова из искомого поля. Т.е. сделать нечто словаря. Словарь держать в отдельной коллекции. Значения могу ссылаться на _id. В таком случае можно еще как-то выбить производительность, но БД сильно распухнет.

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

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

Samu
() автор топика
Ответ на: комментарий от Samu

Как вариант. Если твою строку разбить на слова и поместить их в массив, то возможно через $in прирост получится. Но я такого не проворачивал. Также не забывай про лимит в 16Мб для документа.

Ты поисковик чтоли делаешь на монге? :)

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

В общем, наверное, да. Есть локальная база «пользователей», нужно ее периодически чекать и кое-что в ней искать по мере надобности.

Samu
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.