Can I remove documents of mongodb using regex expression? - mongodb

I have not find a method to do it yet.
If we can not remove documents using regex expression, what can we do to make it done? And why does not mongodb provide such a driver ?

The .remove() method just takes a query object, so regular expressions are just a standard query for MongoDB:
db.collection.remove({ "field": /^string/ })
Removes anything that has "field" that starts with "string"
Look at the documentation for $regex as well.

Documents can be remove using remove() method and $regex query.
For example
db.users.remove({"email" : { $regex : /$test/}})
It will remove all user email starts with 'test'.
db.users.remove({"email" : { $regex : /#yopmail.com$/}})
It will remove all user email ends with 'yopmail.com'
Details are explained here, mongoDB official site

Related

PanacheMongo find with wildcard

I am trying to do a simple find in Panache but I'm stuck with the wildcard operator.
I have:
Model.find("payload.tags.name = ?1", "tag-to")
.stream()
.map(m -> (Model) m)
.collect(Collectors.toList());
and my document looks something like this:
{
...
payload:Object{
swagger:"2.0"
info:Object
host:"petstore.swagger.io"
basePath:"/v2"
tags:Array[
0:Object [
name:"tag-to-find"
description:"a tag i want to find"
]
]
}
}
When I try to find "tag-to-find" it works, but I don't know how to get the wildcards going. In mongoshell i just use db.Model.find({"payload.tags.name": /ag-to-/}) and it works.
What you are using in Mongo shell is a JavaScript regex.
You should also be able to use it with MongoDB with Panache.
You should normaly use the regex with the $regex operator, not sure how Mongo shell handle it but the following should work:
Model.list("payload.tags.name like ?1", "/tag-to/")
I use .list() instead of find() as it directly return the list of documents.
The query used here is what we called PanacheQL query that will maps to a MongoDB native query, you can also use a native query directly (with named or indexed parameters).
Simplified query is explained here: https://quarkus.io/guides/mongodb-panache#simplified-queries

Mongodb Stitch realtime watch

What I intend to achieve is some sort of "live query" functionality.
So far I've tried using the "watch" method. According to the documentation:
You can open a stream of changes that match a filter by calling
collection.watch(delegate:) with a $match expression as the argument.
Whenever the watched collection changes and the ChangeEvent matches
the provided $match expression, the stream’s event handler fires with
the ChangeEvent object as its only argument
Passing the doc ids as an array works perfectly, but passing a query doesn't work:
this.stitch.db.collection<Queue>('queues')
.watch({
hospitalId: this.activehospitalid
}));
I've also tried this:
this.stitch.db.collection<Queue>('queues')
.watch({
$match: {
hospitalId: this.activehospitalid
}
},
));
Which throws an error on the console "StitchServiceError: mongodb watch: filter is invalid (unknown top level operator: $match)". The intention is watch all documents where the field "hospitalId" matches the provided value, or to effectively pass a query filter to the watch() method.
After a long search I found that it's possible to filter, but the query needs to be formatted differently
this.stitch.db.collection<Queue>('queues')
.watch({
$or: [
{
"fullDocument.hospitalId": this.activehospitalid
}
]
},
));
For anyone else who might need this, please note the important fullDocument part of the query. I havent found much documentation relating to this, but I hope it helps

MongoDB - find if a field value is contained in a given string

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.
I can think of 2 ways you could do this:
Option 1
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
Option 2
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 :)
You can use regex to search .
db.company.findOne({"companyname" : {$regex : ".*hello.*"}});
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.

Mongoid, find object by searching by part of the Id?

I want to be able to search for my objects by searching for the last 4 characters of the id. How can I do that?
Book.where(_id: params[:q])
Where the param would be something like a3f4, and in this case the actual id for the object that I want to be found would be:
bc313c1f5053b66121a8a3f4
Notice the last for characters are what we searched for. How can I search for just "part" of my objects id? instead of having my user search manually by typing in the entire id?
I found in MongoDB's help docs, that I can provide a regex:
db.x.find({someId : {$regex : "123\\[456\\]"}}) // use "\\" to escape
Is there a way for me to search using the regular mongo ruby driver and not using Mongoid?
Usually, in Mongoid you can search with a regexp like you normally would with a string in your call to where() ie:
Book.where(:title => /^Alice/) # returns all books with titles starting with 'Alice'
However this doesn't work in your case, because the _id field is not stored as a string, but as an ObjectID. However, you could add (and index) a field on your models which could provide this functionality for you, which you can populate in an after_create callback.
<shameless_plug>
Alternatively, if you're just looking for a shorter solution to the default Mongoid IDs, I could suggest something like mongoid_token which makes it pretty easy to add shorter tokens/ids to your Mongoid documents.
</shameless_plug>

Performing regex queries with PyMongo

I am trying to perform a regex query using PyMongo against a MongoDB server. The document structure is as follows
{
"files": [
"File 1",
"File 2",
"File 3",
"File 4"
],
"rootFolder": "/Location/Of/Files"
}
I want to get all the files that match the pattern *File. I tried doing this as such
db.collectionName.find({'files':'/^File/'})
Yet I get nothing back. Am I missing something, because according to the MongoDB docs this should be possible? If I perform the query in the Mongo console it works fine, does this mean the API doesn't support it or am I just using it incorrectly?
If you want to include regular expression options (such as ignore case), try this:
import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})
Turns out regex searches are done a little differently in pymongo but is just as easy.
Regex is done as follows :
db.collectionname.find({'files':{'$regex':'^File'}})
This will match all documents that have a files property that has a item within that starts with File
To avoid the double compilation you can use the bson regex wrapper that comes with PyMongo:
>>> regx = bson.regex.Regex('^foo')
>>> db.users.find_one({"files": regx})
Regex just stores the string without trying to compile it, so find_one can then detect the argument as a 'Regex' type and form the appropriate Mongo query.
I feel this way is slightly more Pythonic than the other top answer, e.g.:
>>> db.collectionname.find({'files':{'$regex':'^File'}})
It's worth reading up on the bson Regex documentation if you plan to use regex queries because there are some caveats.
The solution of re doesn't use the index at all.
You should use commands like:
db.collectionname.find({'files':{'$regex':'^File'}})
( I cannot comment below their replies, so I reply here )