J'ai créé une collection: Product
les documents suivants ...
{
"_id" : ObjectId("59d0ada3c26584cd8b79fc51"),
"name" : "Produkt Neu"
}
{
"_id" : ObjectId("59d0adafc26584cd8b79fc54"),
"name" : "Produkt2"
}
... et je déclarai un index de texte sur cette collection comme suit:
db.Product.createIndex({ name: "text" })
Je courais le suivant requêtes qui reproduisent fidèlement la situation décrite dans votre question:
// returns one document since there is one document
// which has the text indexed value: "Produkt Neu"
db.Product.find({ $text: { $search: "Produkt Neu" } });
// returns no documents since there is no document
// which has the text indexed value: "Produkt2"
db.Product.find({ $text: { $search: "Produkt -Neu" } })
Vous êtes, je pense, attendre cette requête ...
db.Product.find({ $text: { $search: "Produkt -Neu" } })
... pour revenir le deuxième document au motif que l'exclusion Neu
devrait permettre un match sur le document ayant name=Produkt2
mais ce n'est pas comment MongoDB $text
les recherches fonctionnent. MongoDB $text
recherche ne prend pas en charge la correspondance partielle afin que le terme de recherche Produkt -Neu
(qui évalue comme Produkt
) ne correspondra pas Produkt2
. Pour vérifier cela, j'ai couru la requête suivante:
db.Product.find({ $text: { $search: "Produkt2 -Neu" } })
Cette requête renvoie le deuxième document (à savoir celui avec name=Produkt2
) ce qui prouve que le Tiret (-
) niait avec succès le terme: Neu
.
Sur une note de côté; index de texte MongoDB ne prennent en charge la langue égrappage, de vérifier ce comportement, j'ai ajouté le document suivant ...
{
"_id" : ObjectId("59d0b2b4c26584cd8b79fd7c"),
"name" : "Produkts"
}
... puis couru cette requête ...
db.Product.find({ $text: { $search: "Produkt -Neu" } });
Cette requête renvoie le document avec name=Produkts
car Product
est une racine de Produkts
. En résumé, une recherche $text
trouvera des correspondances où chaque terme de recherche a soit (a) une correspondance sur un monde entier dans l'index de texte ou (b) est une racine reconnue d'un mot entier dans l'index de texte. Remarque: il existe également des correspondances d'expressions, mais celles-ci ne sont pas pertinentes pour les exemples de votre question. L'utilisation du trait d'union sert à modifier les termes de recherche mais ne change pas la façon dont le terme de recherche est évalué.
Plus de détails in the docs et il y a un problème ouvert avec MongoDB concernant supporting partial matching on text indexes.
Si vous avez vraiment besoin de prendre en charge la correspondance partielle, vous souhaiterez probablement ignorer l'index de texte et utiliser l'opérateur $regex
à la place.Bien que la couverture d'index avec l'opérateur $regex
ne soit probablement pas ce que vous attendez, le bref résumé est le suivant: si votre valeur de recherche est ancrée (par exemple Produk
, plutôt que rodukt
), MongoDB peut utiliser un index, mais autrement il ne le peut pas.