Wyszukiwanie tekstu MongoDb z obsługą języków

Nov 22 2020

Mam problemy z wyszukiwaniem tekstu w języku MongoDB. W przypadku niektórych rekordów wyszukiwanie działa świetnie, a dla niektórych w ogóle nie działa.

Mam listę składników, które chciałbym wyszukać. Składniki są w kilku językach i lubię dbać o liczbę pojedynczą i mnogą.

Oto mój przykład

Schemat

{
  translation: [
    {
      language: {
        type: String,
        required: true
      },
      name: {
        type: String,
        required: true
      }
    }
  ],
  calories: {
    "type": Number
  },
  protein: {
    "type": Number
  },
  carbohydrate: {
    "type": Number
  },
  fat: {
    "type": Number
  }
}

Indeks

foodSchema.index( { "translation.name": "text" }, { default_language: "german" } )

Odczytaj indeks z bazy danych

[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_"
    },
    {
        "v" : 2,
        "key" : {
            "_fts" : "text",
            "_ftsx" : 1
        },
        "name" : "translation.name_text",
        "default_language" : "german",
        "background" : true,
        "weights" : {
            "translation.name" : 1
        },
        "language_override" : "language",
        "textIndexVersion" : 3
    }
]

Dokumentacja

{
  calories: 1,
  protein: 2,
  carbohydrate: 3,
  fat: 4,
  translation: [
    {
      _id: ObjectId('5fba87d13ad6404108191670'),
      language: 'german',
      name: 'gurke'
    },
    {
      _id: ObjectId('5fba87d13ad6404108191671'),
      language: 'english',
      name: 'cucumber'
    },
    {
      _id: ObjectId('5fba87d13ad6404108191672'),
      language: 'spanish',
      name: 'pepino'
    }
  ]
}

// ----

{    
  calories: 4,
  protein: 3,
  carbohydrate: 2,
  fat: 1,
  translation: [
    {
      _id: ObjectId('5fba87d13ad6404108191674'),
      language: 'german',
      name: 'huhn'
    },
    {
      _id: ObjectId('5fba87d13ad6404108191675'),
      language: 'english',
      name: 'chicken'
    },
    {
      _id: ObjectId('5fba87d13ad6404108191676'),
      language: 'spanish',
      name: 'pollo'
    }
  ]
}

Wyszukiwanie danych

db.getCollection('foods').find({$text: { $search: "gurke" }}) //works
db.getCollection('foods').find({$text: { $search: "gurken" }}) //works
db.getCollection('foods').find({$text: { $search: "cucumber" }}) //works
db.getCollection('foods').find({$text: { $search: "cucumbers" }}) //works
db.getCollection('foods').find({$text: { $search: "huhn" }}) //works
db.getCollection('foods').find({$text: { $search: "hühner" }}) //works
db.getCollection('foods').find({$text: { $search: "chicken" }}) // no result
db.getCollection('foods').find({$text: { $search: "chickens" }}) //no result
db.getCollection('foods').find({$text: { $search: "pepino" }}) //no result

Dokumentacja z MongoDb mówi: https://docs.mongodb.com/manual/tutorial/specify-language-for-text-index/

Domyślny język powiązany z indeksowanymi danymi określa zasady analizowania korzeni słów (tj. Podstawników) i ignorowania słów pomijanych.

  • Czy to oznacza, że ​​obsługiwany jest tylko język domyślny?
  • Dlaczego działa na ogórki, a nie na kurczaka?

Sprawdzałem też słowa stop dla każdego kurczaka. https://github.com/mongodb/mongo/blob/master/src/mongo/db/fts/stop_words_english.txt

Dziękuję za pomoc!

Odpowiedzi

1 Minsky Nov 22 2020 at 17:06

Problemem nie jest indeks, to prawda, ale musisz go dodać $languagelub używa on języka domyślnego (przynajmniej podczas używania $text). Próbować

 db.collection.find({$text:{$search:"pollo", $language:"spanish"}})

$language Dokumenty

Jeśli nie zostanie określony, wyszukiwanie będzie używać domyślnego języka indeksu.

Również, jeśli biegasz

 db.collection.find({$text:{$search:"pollo"}}).explain()

Dowiesz się, że zapytanie używa języka domyślnego.