Текстовый индекс Атласа MongoDB с автозаполнением не соответствует

#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, может быть, даже подать запрос на функцию.