J'ai mongodb avec un $text-Index
et des éléments comme celui-ci:
{
foo: "my super cool item"
}
{
foo: "your not so cool item"
}
Si je cherche avec
mycoll.find({ $text: { $search: "super"} })
je reçois le premier article (correct).
Mais je veux aussi chercher avec "uper" pour obtenir le premier article - mais si j'essaye:
mycoll.find({ $text: { $search: "uper"} })
Je n'obtiens aucun résultat.
Ma question: S'il y a un moyen d'utiliser $ text pour qu'il trouve les résultats avec une partie de la chaîne de recherche? (par exemple, comme '%uper%'
dans mysql
)
Attention: je ne demande pas une recherche uniquement regex - je demande une recherche regex dans une recherche $ text!
Il n'est pas possible de le faire avec l'opérateur $text
.
Les index de texte sont créés avec les termes inclus dans la valeur de chaîne ou dans un tableau de chaînes. La recherche est basée sur ces idexes.
Vous pouvez uniquement grouper des termes sur un livre sans en prendre partie.
Lire $text
référence opérateur et description des index de texte .
Ce que vous essayez de faire dans votre deuxième exemple est la recherche de préfixe avec caractères génériques dans votre collection mycoll
sur le champ foo
. Ce n’est pas une fonction pour laquelle la fonctionnalité de recherche de texte est conçue et il n’est pas possible de le faire avec l’opérateur $text
. Ce comportement n'inclut pas la recherche de préfixe par un caractère générique sur un jeton donné dans le champ indexé. Cependant, vous pouvez également effectuer une recherche de regex comme suggéré par d'autres. Voici ma procédure pas à pas:
>db.mycoll.find()
{ "_id" : ObjectId("53add9364dfbffa0471c6e8e"), "foo" : "my super cool item" }
{ "_id" : ObjectId("53add9674dfbffa0471c6e8f"), "foo" : "your not so cool item" }
> db.mycoll.find({ $text: { $search: "super"} })
{ "_id" : ObjectId("53add9364dfbffa0471c6e8e"), "foo" : "my super cool item" }
> db.mycoll.count({ $text: { $search: "uper"} })
0
L'opérateur $text
prend en charge la recherche d'un seul mot, la recherche d'un ou plusieurs mots ou la recherche d'une phrase. Le type de recherche que vous souhaitez n'est pas pris en charge
La solution regex:
> db.mycoll.find({foo:/uper/})
{ "_id" : ObjectId("53add9364dfbffa0471c6e8e"), "foo" : "my super cool item" }
>
La réponse à votre dernière question: pour faire le style mysql %super%
dans mongoDB, vous devrez probablement faire:
db.mycoll.find( { foo : /.*super.*/ } );
Je n'ai pas assez de réputation pour commenter la solution de jasenkoh, mais c'est clairement la meilleure façon de gérer cette situation.
En situation d'OP, je voudrais:
db.mycoll.createIndex( { foo: "text" } )
db.mycoll.createIndex( { foo: 1 } )
db.mycoll.find({$or: [{$text: {$search: 'uper'}}, {foo: {$regex: 'uper'}}]})
Pour de meilleures performances (mais des résultats légèrement différents), remplacez la dernière ligne par:
db.mycoll.find({$or: [{$text: {$search: 'uper'}}, {foo: {$regex: '^uper'}}]})
Comme francadaval l'a dit, l'index de texte recherche par termes, mais si vous combinez regex
et text-index
, vous devriez être bon.
mycoll.find({$or: [
{
$text: {
$search: "super"
}
},
{
'column-name': {
$regex: 'uper',
$options: 'i'
}
]})
Assurez-vous également que vous avez appliqué à la colonne un index normal autre que l'index de texte.
Vous auriez pu réaliser est as-
db.mycoll.find( {foo: { $regex : /uper/i } })
Ici, "i" est une option, indique une recherche insensible à la casse