Morphia/MongoDB: упорядочивание результатов поиска по расширенным запросам

Я новичок в Morphia, MongoDB и документо-ориентированные базы данных в целом. Я ищу общее руководство о том, как подойти к следующей проблеме.

У нас есть БД с около 500 тыс. Book документов.

{ 
   "isbn" : "0-691-01305-5", 
   "title" : "For Whom the Bell Tolls", 
   "titleFTS" : [
       "bell",
       "toll" ],
   "author" : "Hemingway, Ernest",
   "ratingsCount" : 138, 
   "rating" : "3.5", 
   "sales" : 10245
   "price" : "12.95", 
   "category" : "fiction", 
   "description" : "The story of a young American in the International Brigades attached to a republican guerilla unit during the Spanish Civil War.",
   "descriptionFTS" : [
       "story",
       "young",
       "americ",
       "internat",
       "brigade",
       "attach",
       "republic",
       "guerilla",
       "unit",
       "spanish",
       "civil",
       "war"]
}

Нам нужно выполнить полнотекстовый поиск по полям заголовка и описания. С этой целью я создал массивы titleFTS и descriptionFTS, содержащие слова из полей title и description соответственно, отфильтрованные по стоп-словам, а затем объединенные.

При поиске пользователи вводят ключевые слова, и мы возвращаем книги, соответствующие всем введенным терминам, например:

db.Book.find({ titleFTS : { $all: ['spanish', 'civil', 'war']}})
db.Book.find({ descriptionFTS : { $all: ['spanish', 'civil', 'war']}})

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

  1. книги, соответствующие условиям поиска в полях titleFTS и descriptionFTS
  2. книги, совпадающие только в поле titleFTS
  3. книги, совпадающие только в поле descriptionFTS
  4. книги с наибольшим количеством из sales
  5. книги с самым высоким rating
  6. книги с самым высоким ratingscount

Наше приложение написано на Java и использует API MorphiaDB. Я могу представить, как написать Comparator на языке Java. для такого рода вещей довольно легко, но, очевидно, я хотел бы сделать заказ на уровне БД.

Что, наконец, подводит меня к вопросу: можно ли это сделать с помощью Morphia API? Или мне нужно углубиться в написание Javascript с помощью DB.command()? Требуется ли Map/Reduce? Если это так, то подсказка о том, как реализовать map/reduce для этой проблемы, очень поможет.


person George Armhold    schedule 18.02.2011    source источник


Ответы (2)


На данный момент я настоятельно рекомендую внешний полнотекстовый движок, такой как Solr или ElasticSearch. Возможности MongoDB, связанные с полнотекстовым поиском, действительно не подходят для настоящего полнотекстового решения. Ваш подход с предварительным стеммингом и т. д. - это просто грязный обходной путь. Пока MongoDB не обеспечивает подходящей полнотекстовой интеграции, используйте внешнее решение, если вы заинтересованы в серьезном и работающем решении.

person Andreas Jung    schedule 18.02.2011
comment
Хм, я использовал Lucene в (далеком) прошлом, но не знал о Solr. Хотя он будет довольно хорошо обрабатывать FTS, как вы думаете, сможет ли Solr также обрабатывать другие типы запросов, которые я упомянул? Или мне нужно продолжать использовать для этого MongoDB (или какую-то СУБД) в сочетании с Solr? - person George Armhold; 18.02.2011
comment
Lucene и Solr в основном одинаковы. И Solr, и ElasticSearch могут обрабатывать все виды сложных запросов, ранжирование, сортировку и т. д. - person Andreas Jung; 19.02.2011

Lucene и solr позволяют создавать сложные булевы запросы ко многим полям, включая запросы диапазона чисел и даже запросы на определение местоположения.

person yura    schedule 20.02.2011