Я новичок в 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']}})
Это прекрасно работает, но теперь мы подошли к сложной части: мы хотели бы упорядочить результаты вышеуказанных запросов на основе нескольких критериев. Один из таких предлагаемых порядков следующий:
- книги, соответствующие условиям поиска в полях
titleFTSиdescriptionFTS - книги, совпадающие только в поле
titleFTS - книги, совпадающие только в поле
descriptionFTS - книги с наибольшим количеством из
sales - книги с самым высоким
rating - книги с самым высоким
ratingscount
Наше приложение написано на Java и использует API MorphiaDB. Я могу представить, как написать Comparator на языке Java. для такого рода вещей довольно легко, но, очевидно, я хотел бы сделать заказ на уровне БД.
Что, наконец, подводит меня к вопросу: можно ли это сделать с помощью Morphia API? Или мне нужно углубиться в написание Javascript с помощью DB.command()? Требуется ли Map/Reduce? Если это так, то подсказка о том, как реализовать map/reduce для этой проблемы, очень поможет.