I wanted to run a query that finds the following document from MongoDB database
{field1:"foo",field2:"barfoobar"}
I know for equality I can use the following query:
.find({ $where : "this.field1 == this.field2" })
In C#
new BsonDocument("$where", new BsonJavaScript("this.field1 == this.field2"));
But how I can use regex in above query?
Somthing like:
.find({ $where : "this.field1 like this.field2" })
And in C# ?
Use the following query and check if it works for you. Let me know if it helped:
db.col.find( { $where: function() {
var regex = new RegExp(this.field1);
return (regex.test(this.field2))
} }).pretty();
The query above turns foo into a regex (something like /foo/) and checks if field2 matches the regex you passed.
FYI: The following statement was taken from mongodb website. Take it into consideration:
Changed in version 3.6: The $expr operator allows the use of aggregation expressions within the query language. $expr is faster than $where because it does not execute JavaScript and should be preferred where possible.
Related
Current JSON object is
{"_id":{"$oid":"613ed8098709b6402ab91ddd"},"employeeid":1187,"name":"John Steight","salary":75000},
{"_id":{"$oid":"613ed8788709b6402ab91dde"},"employeeid":2455,"name":"Syed","salary":90000},
{"_id":{"$oid":"613ed8c78709b6402ab91ddf"},"employeeid":24113,"name":"Wright John","salary":65000}
Use the $where operator to find employees where the name contains John
Here is my command:
db.HR.find({$where: "this.name == /$John$/"}).
It returned nothing.
If want to use $where, you should pass it a valid JavaScript expression. You can do it like this:
db.collection.find({
$where: "this.name.includes('John')"
})
Working example
Note that you don't have to use $where. You can do it with $regex, like this:
db.collection.find({
name: { "$regex": "John" }
})
Working example
Following the MongoDB documentation, you can use the $in operator with a regular expression like wise db.inventory.find( { tags: { $in: [ /^be/, /^st/ ] } } ). Is there a way to achieve the same result using mongoengine?
For example pass {"tags__in": ["/^be/", "/^st/"]} to my query?
I don't think this is supported by MongoEngine in normal query construct (i.e I doubt that Doc.objects(tags__in=["/^be/", "/^st/"] will work)) but there is support for __raw__ query (https://docs.mongoengine.org/guide/querying.html#raw-queries)
so the following should work
Inventory.objects(__raw__={"tags": { "$in":["/^be/", "/^st/"]}})
I want to find all documents where a given field is a prefix of an input value. In SQL it looks like this:
... where input_value like concat(field, '%')
I want to do this in Mongo 2.4.8 (very much preferably) without using $where. It's easy with $where but I can't use $where because I want to use a pipeline so I can use $project to derive some fields. And apparently you can't use $where in pipeline a $match. And as far as I can see you can't use the pipeline $project-ion operators in a normal find() projection - argh.
One way of doing it would be to construct a $regex pattern. The below example demonstrates the construction and usage of a regexp. There are alternative ways one could build a regexp.
sample insert scripts:
db.t.insert([
{"name":"sampleString"},
{"name":"sam"},
{"name":"s"},
{"name":"sample"}
])
sample code:
var input = "sample";
var pattern = ''
input.split('').reverse().forEach(function(i,j){pattern = '('+i+pattern+')?'}) // (s(a(m(p(l(e)?)?)?)?)?)?
var regexp = new RegExp("^"+pattern+"$");
and use it as:
db.t.find({"name":{$regex:regexp}});
or:
db.t.aggregate([
{$match:{"name":{$regex:regexp}}}
])
That would give you:
{ "_id" : ObjectId("56cba179d99d86bcb7251107"), "name" : "sam" }
{ "_id" : ObjectId("56cba179d99d86bcb7251108"), "name" : "s" }
{ "_id" : ObjectId("56cba19fd99d86bcb725110c"), "name" : "sample" }
And as far as I can see you can't use the pipeline $project-ion operators in a normal find() projection - argh.
You can definitely, use project fields in a find() statement as below, though you cannot modify the projected field.
db.t.find({"name":{$regex:regexp}},{"fieldToProject":1});
I prepare get some objects in the mongodb.
{number1:123,number2:321}
{number1:222,number2:4532}
For example, these are what i have in the database. But now, i want to get them by the value of number1 + number2.
How to do it ?
One option that no one has actually said here is to use the aggregation framework. Better than using $where since it will be faster and you can actually sort on that return and more as such:
db.c.aggregate([
{'$project': {sumField: {$add: ['$number1', '$number2']}}},
{'$sort': {sumField: 1}}
]);
Like so. Better than using the inbuilt JS, plus with an index and covered query you could make this faster since aggregation, unlike $where can actually use an index.
Use $where operator
db.myCollection.find( {'$where':'this.number1 + this.number2 = 200'})
Adding a virtual to your schema in mongodb will help you
YourSchema.virtual('numbersum')
.get(function () {
return this.number1 + ' ' + this.number2;
})
Then, you´ll be able to do that:
db.yourcollection.find().sort({numbersum:1});
Check this answer. Sorting by virtual field in mongoDB (mongoose)
EDIT this will work only when using mongoose as connector
It may be related to this question
Basic GROUP BY statement using OPA MongoDB high level API.
I want to be able to retrieve a list of documents which "name" field value contains a given string.
Here's my documents list :
{name: "Charles-Hugo"},
{name: "Jean Pierre"},
{name: "Pierre Dupont"},
I want to be able to only retrieve documents which name contains the "Pierre" string: Jean Pierre, and Pierre Dupont.
I know this isn't possible with the MongoDB high-level API.
I've looked in the low-level API functions but I don't know what's the easiest way to retrieve my documents in safe Opa type.
Also I'd like to add skip/limit options to my query.
Any idea ?
The DbGen automation mechanism in Opa has support for this:
DbSet.iterator(/path/data[name =~ pattern])
As #Henri pointed out there is regular expression searching support in Opa since commit [enhance] DbGen: add case insensitive regex operator =~ what is very nice.
Mind that it is using $regex operator, not the full-text index and it may result with some performance loss :( As MongoDB documentation says $regex operator uses indexes in limited way - only for prefix search: pattern ^Jean. Searching for Jean anywhere in text will require full scan.
Personally, I am using full-text index feature of Mongo with Opa's "low-level" API for the $text command like this:
function list({float score, Article.id id}) textSearch(string query) {
function onfailure(failure) {
cat.error("textSearch({{~query}}): {failure}");
[];
}
function onsuccess(success) {
function aux(~{name,value}) {
name == "results";
}
match (List.filter(aux, success)) {
| [] :
// `results` field not found - error
onfailure(success);
| results:
cat.debug("textSearch({~{query}}): {results}");
function ({~score, obj: ~{id}}) {
~{score, id}
}
|> List.map(_, Bson.doc2opa(results) ? []);
}
}
opts = [H.str("search", query), H.doc("project", [H.i32("_id",0), H.i32("id",1)])];
// { search: query, project: {_id:0, id:1}, }
// |> Bson.opa2doc
outcome = MongoCommands.simple_str_command_opts(ll_db, db_name, "text", coll_name, opts);
MongoCommon.outcome_map(outcome, onsuccess, onfailure)
}
Feature is available in Mongo since 2.4 as experimental (you have to turn it on by special configuration option) and in 2.6 as stable (turned on by default).