MongoDb-Textsuche mit Sprachunterstützung

Nov 22 2020

Ich habe Probleme mit der Sprachtextsuche von MongoDB. Bei einigen Datensätzen funktioniert die Suche hervorragend und bei einigen Datensätzen überhaupt nicht.

Ich habe eine Liste mit Zutaten, nach denen ich suchen möchte. Die Zutaten sind in mehreren Sprachen und ich kümmere mich gerne um Singular und Plural.

Hier ist mein Beispiel

Schema

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

Index

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

Index aus DB lesen

[
    {
        "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
    }
]

Aufzeichnungen

{
  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'
    }
  ]
}

Daten suchen

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

Die Dokumentation von MongoDb sagt: https://docs.mongodb.com/manual/tutorial/specify-language-for-text-index/

Die den indizierten Daten zugeordnete Standardsprache bestimmt die Regeln zum Analysieren von Wortwurzeln (dh Stemming) und Ignorieren von Stoppwörtern.

  • Bedeutet dies, dass nur die Standardsprache unterstützt wird?
  • Warum funktioniert es für Gurken, aber nicht für Hühnchen?

Ich überprüfte auch die Stoppwörter für jedes Huhn. https://github.com/mongodb/mongo/blob/master/src/mongo/db/fts/stop_words_english.txt

Danke für deine Hilfe!

Antworten

1 Minsky Nov 22 2020 at 17:06

Das Problem ist nicht der Index, das ist richtig, aber Sie müssen ihn hinzufügen $languageoder er verwendet die Standardsprache (zumindest bei Verwendung $text). Versuchen

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

$language Docs

Wenn nicht angegeben, verwendet die Suche die Standardsprache des Index.

Auch wenn du rennst

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

Sie werden feststellen, dass die Abfrage die Standardsprache verwendet.