2017-09-28 3 views
1

J'utilise MongoDB, Version 3.4.5 et j'ai essayé d'exclure un terme avec - (moins). Pour une raison quelconque, cela ne fonctionne pas. Ce sont mes essais:

db.Product.find() 
    { "_id" : ObjectId("59cbfcd01889a9fd89a3565c"), "name" : "Produkt Neu", ... 
    { "_id" : ObjectId("59cc7d941889a4f4c2f43b14"), "name" : "Produkt2", ... 

db.Product.find({ $text: { $search: 'Produkt -Neu' } }); 

db.Product.find({ $text: { $search: "Produkt -Neu" } }); 

db.Product.find({ $text: { $search: "Produkt2" } }); 
    { "_id" : ObjectId("59cc7d941889a4f4c2f43b14"), "name" : "Produkt2", ... 

db.Product.dropIndexes() 

db.Product.createIndex({ name: "text" }) 
    { 
     "nIndexesWas" : 2, 
     "msg" : "non-_id indexes dropped for collection", 
     "ok" : 1 
    } 

    { 
     "createdCollectionAutomatically" : false, 
     "numIndexesBefore" : 1, 
     "numIndexesAfter" : 2, 
     "ok" : 1 
    } 

db.Product.find({ $text: { $search: "Produkt -Neu" } }); 

db.Product.find({ $text: { $search: "Produkt Neu" } }); 
    { "_id" : ObjectId("59cbfcd01889a9fd89a3565c"), "name" : "Produkt Neu", ... 

Est-ce que quelqu'un sait ce que je dois faire pour le faire fonctionner avec - (moins).

Répondre

1

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.