Reputation: 2529
Is it possible to query documents where a specific field is contained in a given string?
for example if I have these documents:
{a: 'test blabla'},
{a: 'test not'}
I would like to find all documents that field a
is fully included in the string "test blabla test"
, so only the first document would be returned.
I know I can do it with aggregation
using $indexOfCP
and it is also possible with $where
and mapReduce
. I was wandering if it's possible to do it in find
query using the standard MongoDB operators (e.g., $gt, $in).
thanks.
Upvotes: 3
Views: 2493
Reputation: 2207
If you are using Mongo v3.6+, you can use $expr.
As you mentioned $indexOfCP
can be used to get index, here it will be
{
"$expr": {
{$ne : [{$indexOfCP: ["test blabla test", "$a"]}, -1]}
}
}
The field name should be prefixed with a dollar sign ($), as $expr
allows filters from aggregation pipeline.
Upvotes: 0
Reputation: 2159
I can think of 2 ways you could do this:
Using $where:
db.someCol.find( { $where: function() { return "test blabla test".indexOf(this.a) > -1; } }
Explained: Find all documents whose value of field "a" is found WITHIN some given string.
This approach is universal, as you can run any code you like, but less recommended from a performance perspective. For instance, it cannot take advantage of indexes. Read full $where considerations here: https://docs.mongodb.com/manual/reference/operator/query/where/#considerations
Using regex matching trickery, ONLY under certain circumstances; below is an example that only works with matching that the field value is found as a starting substring of the given string:
db.someCol.find( { a : /^(t(e(s(t( (b(l(a(b(l(a( (t(e(s(t)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?)?$/ } )
Explained: Break up the components of your "should-be-contained-within" string and match against all sub-possibilities of that with regex.
For your case, this option is pretty much insane, but it's worth noting as there may be specific cases (such as limited namespace matching), where you would not have to break up each letter, but some very finite set of predetermined parts. And in that case, this option could still make use of indexes, and not suffer the $where performance pentalties (as long as the complexity of the regex doesn't outweigh that benefit :)
Upvotes: 1
Reputation: 1878
You can use regex to search .
db.company.findOne({"companyname" : {$regex : ".*hello.*"}});
Upvotes: 0