#mongodb #mongodb-atlas
#mongodb #mongodb-atlas
Вопрос:
Я создал текстовый индекс в одной из моих коллекций баз данных, для каждой из которых установлено автозаполнение. Поля коллекции, которые я проиндексировал, — это имя, фамилия и адрес электронной почты. Ниже приведено то, что я использовал для создания своего текстового индекса. Это успешно:
{
"mappings": {
"dynamic": false,
"fields": {
"email": [
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 3,
"tokenization": "edgeGram",
"type": "autocomplete"
}
],
"firstname": [
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 3,
"tokenization": "edgeGram",
"type": "autocomplete"
}
],
"surname": [
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 3,
"tokenization": "edgeGram",
"type": "autocomplete"
}
]
}
}
}
Когда я запускаю следующий запрос в оболочке MongoDB, я не получаю никаких ошибок, но и никаких результатов, когда поле фамилии точно соответствует запросу:
db.users.aggregate([ { "$search": { "autocomplete":
{ "query": "janson","path": "surname", "fuzzy":
{ "maxEdits": 2, "prefixLength": 3 } } } }])
Я также пробовал это со всеми тремя полями коллекции в индексе:
db.users.aggregate([ { "$search": { "autocomplete":
{ "query": "janson","path": ["firstname","surname", "email"], "fuzzy":
{ "maxEdits": 2, "prefixLength": 3 } } } }])
Это дает мне следующую ошибку:
«Удаленная ошибка от mongot :: вызвана :: «путь» должен быть строкой (из «автозаполнения»)»,
Я не понимаю, как ошибка может быть связана с моим определением индекса, потому что оно проверяется atlas и существует на сервере. В чем может быть проблема?
Спасибо
Редактировать
упрощенный запрос:
db.groups.aggregate([ { "$search": { "autocomplete": { "query": "test", "path": "title" } } }])
Спецификация индекса Атласа:
{
"mappings": {
"dynamic": false,
"fields": {
"title": [
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 3,
"tokenization": "edgeGram",
"type": "autocomplete"
}
]
}
}
}
Простой документ, который, по мнению Atlas, проиндексирован на 100%:
{
"_id": {
"$oid": "5f773d551dd78dfa97219ae2"
},
"title": "test"
}
Комментарии:
1. Для меня работает идеально. Ваш индекс завершен? Это занимает некоторое время.
2. Да, в atlas указано, что он проиндексирован на 100%. Я подумал, что это может быть случай, когда предыдущие документы не были проиндексированы, поэтому я добавил еще один, но он по-прежнему ничего не возвращает. Я даже удалил нечеткий оператор, чтобы упростить его, но ничего не помогает.
3. Можете ли вы добавить пример документа? Пожалуйста, только основные поля
4. Да, я добавил изменения в вопрос
5. Думаю, я понял. Я смог воспроизвести. Смотрите мой ответ.
Ответ №1:
Вам необходимо указать имя индекса, если вы используете индекс, отличный от индекса по умолчанию:
db.users.aggregate([ {
"$search": {
"index": "<REPLACE_WITH_INDEX_NAME>",
"autocomplete": {
"query": "janson",
"path": "surname",
"fuzzy": {
"maxEdits": 2,
"prefixLength": 3
}
}
}
}])
<REPLACE_WITH_INDEX_NAME>
на SearchIndex1
изображении ниже:
Комментарии:
1. Спасибо, друг. Я создал свой первый индекс для трех текстовых полей, но когда я указываю все три из них в пути, я получаю ошибку, описанную в вопросе выше. Вы знаете, как это обойти?
2.Нравится автозаполнение из 3 полей? Способа нет. Это не поддерживается. Они явно выделили его на docs.atlas.mongodb.com/reference/atlas-search/autocomplete /…
The autocomplete operator does not support multi in the field path.
3. Да, я это видел. Почему можно успешно добавить три поля автозаполнения в индекс, если эта функциональность не существует, возможно, есть способ объединить результат трех отдельных поисков по каждому полю?
4. Я думаю, «Почему» — риторический вопрос. Попробуйте составной поиск или фасеты. В конце концов, это конвейер.
5. Поиск является специфичным для Atlas предложением и, в отличие от Mongo, не является открытым исходным кодом. Я могу предположить, что. В конце концов, они построили его поверх Lucene. Насколько я понимаю, индекс «автозаполнения» — это единственный вариант использования токенизатора ngram. Таким образом, вы можете указать, какие поля вы хотите проиндексировать, а затем использовать любое из индексированных полей для поиска. Ограничение одного поля, вероятно, связано с компромиссами реализации. Должно быть, потому, что индекс довольно тяжелый. Попробуйте поговорить со службой поддержки Atlas, может быть, даже подать запрос на функцию.