Поиск по текстовому индексу MongoDB
Я создал коллекцию в Монго БД, как показано ниже
db.articles.insert([
{ _id: 1, subject: "one", author: "abc", views: 50 },
{ _id: 2, subject: "lastone", author: "abc", views: 5 },
{ _id: 3, subject: "firstone", author: "abc", views: 90 },
{ _id: 4, subject: "everyone", author: "abc", views: 100 },
{ _id: 5, subject: "allone", author: "efg", views: 100 },
{ _id: 6, subject: "noone", author: "efg", views: 100 },
{ _id: 7, subject: "nothing", author: "abc", views: 100 }])
после этого я дал текстовую индексацию теме и автору поля.
db.articles.createIndex(
{subject: "text",
author: "text"})
Сейчас я пытаюсь найти слово с "один" в проиндексированном поле. Когда я выполняю запрос...
db.articles.count({$text: {$search: "\"one\""}})
... результат 1
,
Проблема в том, что когда я хочу сочетание слов "один", "abc"...
db.articles.count({$text: {$search: "\"one\" \"abc\""}}
... это дает результат как 4
, Включая записи, которые содержат имя субъекта как "lastone", "firstone", "Everyone", "One" в качестве результата.
Итак, мой вопрос заключается в том, почему первый запрос не получает 4 записи? И как я могу написать запрос, который может получить 4 записи со словом "один"?
1 ответ
Эта команда...
db.articles.count({$text: {$search: "\"one\""}})
... будет считать документы, имеющие точную фразу "one"
, Существует только один такой документ, следовательно, результат 1
,
Запросы с использованием значения "one" должны возвращаться только для документа, поскольку существует только один документ, содержащий "one" или некоторое значение, для которого "one" является основой. Из документов:
Для поиска текста без учета регистра и диакритического
$text
Оператор соответствует полному основному слову. Таким образом, если поле документа содержит слово blueberry, поиск по синему слову не будет соответствовать. Тем не менее, черника или черника будут соответствовать.
Глядя на документы по вашему вопросу...
one
это не стебельeveryone
one
это не стебельlastone
one
это не стебельallone
one
это не стебельfirstone
one
это не стебельnoone
... так что ни один из этих документов не будет сопоставлен по значению one
,
Вы можете, конечно, запросить несколько значений. Например:
Документы предполагают, что это следует оценивать как
one or abc
и это правильно возвращает 5:db.articles.count({$text: {$search: "one abc"}})
Документы предполагают, что это следует оценивать как
"abc" AND ("abc" or "one")
и это правильно возвращает 5:db.articles.count({$text: {$search: "\"abc\" one"}})
Документы предполагают, что это следует оценивать как
"one" AND ("one" or "abc")
но это как-то возвращает 4:db.articles.count({$text: {$search: "\"one\" abc"}})
В последнем примере MongoDB включает документы с темой "one", "lastone", "firstone", "Everyone", но исключает документ с темой "none". Это говорит о том, что он каким-то образом считал "один" основой "последнего", "первого" и "каждого", но при выполнении count({$text: {$search: "one"}})
это возвращается 1
что ясно указывает на то, что one
не рассматривается как основа "lastone", "firstone" и "всех".
Я подозреваю, что это может быть ошибкой, и ее стоит поднять с MongoDB.
Впрочем, вполне возможно, что в действительности вам нужен частичный поиск строк. $regex
может работать. Следующий запрос...
db.articles.count({ subject: { $regex: /one$/ }, author: { $regex: /abc$/ } })
... означает что-то вроде count where subject like '%one%' and author like '%abc%'
и для ваших документов, которые возвращаются 4
т.е. документы где subject
является одним из "один", "последний", "первый", "все", "все", "никто" и author
это "abc".