MongoDB проверяет наличие нескольких совпадений регулярных выражений в списке для свободного текстового поиска - PullRequest
4 голосов
/ 09 марта 2012

Я устанавливаю базу данных mongoDB, чтобы разрешить (простой) поиск по ключевым словам с использованием многопользовательских клавиш, как рекомендовано здесь . Запись тоже похожа:

{ title: { title: "A river runs through", _keywords: ["a","river","runs","through"] ) , ... }

Я использую серверную часть nodejs, поэтому использую javascript. Следующий запрос будет соответствовать (он был запущен в терминале Монго):

> db.torrents_sorted.find({'title._keywords' : {"$all" : ["river","the"]} }).count()
210

Однако это не так:

> db.torrents_sorted.find({'title._keywords' : {"$all" : ["/river/i","/the/i"]} }).count()
0

> db.torrents_sorted.find({'title._keywords' : {"$all" : [{ "$regex" : "river", "$options" : "i" },{ "$regex" : "the", "$options" : "i" }]} }).count()
0

Использование одного регулярного выражения (без использования $ и / или $ all) соответствует:

db.torrents_sorted.find ({'title._keywords': {"$ regex": "river", "$ options": "i"}}). Count () 1461

Интересно, что использование python и pymongo для компиляции регулярных выражений работает:

>>> db.torrents_sorted.find({'title._keywords': { '$all': [re.compile('river'), re.compile('the')]}}).count();
236

Я не обязательно ищу решение, которое использует регулярные выражения, однако требуется, чтобы ключевые слова соответствовали более коротким строкам, чтобы "riv" соответствовало "реке", что кажется идеальным для регулярных выражений (или LIKE в sql).

Моя следующая идея - попытаться передать функцию javascript, которая выполняет сопоставление регулярного выражения в списке, или, возможно, передать отдельную функцию для каждого регулярного выражения (это, похоже, кричит мне на хак :), хотя я предполагаю, это будет медленнее, а производительность очень важна.

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Возможно, вы захотите использовать оператор $ и.

0 голосов
/ 11 марта 2012

Хорошо, у меня есть ответ, это немного интересно по-другому. Ошибка, с которой я столкнулся при регулярных выражениях, существует в версии 1.8 mongodb и была устранена, она показана здесь .

К сожалению, хостинговая компания, присматривающая за банкоматом базы данных, не может предложить версию 2.0, а ключевое слово $ и было добавлено в версии 2.0, хотя спасибо за помощь в отладке Samarth.

Поэтому вместо этого я написал функцию javascript для выполнения сопоставления с регулярным выражением:

function () {
  var rs = [RegExp(".*river.*"), RegExp(".*runs.*")];

  for(var j = 0; j < rs.length; j++) {
    var val = false;
    for (var i = 0; !val && i < this.title._keywords.length; i++)
      val = rs[j].test(this.title._keywords[i]);

    if(!val) return false;
  }
  return true;
}

Это выполняется за O (n ^ 2) времени (не очень круто), но завершится ошибкой в ​​линейном времени, если первое регулярное выражение не совпадает ни по одному из ключевых слов (так как я ищу дизъюнкцию).

Любой вклад в оптимизацию этого был бы очень признателен, хотя, если это лучшее решение, которое я могу найти для 1.8, мне, возможно, придется найти где-то еще, чтобы сохранить мою базу данных в ближайшем будущем;).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...