Matching field by omitting spaces - MongoDB - javascript

I'm trying to find the mongo document by matching the "Tel" field value,
{
"_id" : ObjectId("54f047aa5b9e5c7c13000000"),
"data" : [
{
"Id" : "1",
"Country" : "India",
"Timezone" : "Europe/Paris",
**"Tel" : "03 20 14 97 70",**
"Prenom" : "ddd",
"Email" : "ddd#gmail.com",
"City" : "Chennai",
"date" : "",
"active" : "true"
}
]
}
how to fetch the above document from mongo collection using the below find method without space in "Tel" field,
>db.test.find({"data.Tel":"0320149770"})
Please can anyone help me !!!

If this is what you really want to do on a regular basis then you are best off adding another field to the document that has the string present without any spaces.
The reason why is though there are functions you can perform to do the search, none of the methods are able to use an index to match the document, so this means scanning everything in the collection in order to find a match.
You can do this with JavaScript evaluation in a $where clause:
db.test.find(function() {
return this.data.some(function(el) {
el.Tel.replace(/ /g,"") == "0320149770"
});
});
But don't do that because it's really bad. you are better off just updating all the data instead:
db.test.find().forEach(function(doc) {
doc.data = doc.data.map(function(el) {
el.TelNum = el.Tel.replace(/ /g,"");
})
db.test.update({ "_id": doc._id },{ "$set": { "data": doc.data } });
})
Or something along those lines to have a field without spaces all ready to search on directly.

Related

Mongodb native driver chain queries

I am new to queries in mongodb. I have a document like this -
{
"_id" : ObjectId("5eb0f70f88cd051e7839325c"),
"id" : "1",
"arrayInfo" : [ {"color":"red"}, {"color":"black"}, {"color":"cyan"} ]
}
There are many documents in this format with changing ids and colors inside arrayInfo. I want to do something like -
Find record with id "1" -> Display object inside array info with {"color" : "cyan"}
I believe I have to chain queries after finding like this -
db.collection('Records').findOne({id:"1"}).**something**
Any help will be appreciated thanks.
if(id===1){
res.arrayInfo.map(item => console.log(item.color))
}
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
enter link description here
If no operator is specified, MongoDB by default performs array element matching when the document stores an array. Thus you can simply do:
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.findOne({id:'1',arrayInfo:{color:'cyan'}})
{
"_id" : ObjectId("5eb0f70f88cd051e7839325c"),
"id" : "1",
"arrayInfo" : [
{
"color" : "red"
},
{
"color" : "black"
},
{
"color" : "cyan"
}
]
}
To match one field in the array instead of the complete array element, use $elemMatch.

Remove field from an embedded document

I am trying to execute a pretty straight forward script to remove all of my empty values from my document. The document has this structure:
{ "_id" : ObjectId("5a75caa4ce7a49e7d8474a40"),
"icao" : "MLA",
"name" : "40-Mile Air",
"callsign" : "MILE-AIR",
"country" : "US",
"alid" : 10,
"mode" : "F",
"active" : "Y",
"routes" : [ { "codeshare" : "",
"dst_ap" : "TKJ",
"dst_apid" : 7235,
"equipment" : "CNA",
"rid" : 46585 } ]
The script I am executing is this:
db.airlines.updateMany(
{ codeshare: "" },
{ $unset: {codeshare : 1}},
)
However after running I am getting this error:
2018-02-07T10:17:35.634+0000 E QUERY [thread1] SyntaxError: missing : after property id #(shell):3:21
Apply the $unset operator together with the $ positional operator in your update to remove the embedded codeshare field.
The $ positional operator will identify the correct element in the array to update without explicitly specifying the position of the element in the array, thus your final update statement should look like:
db.airlines.updateMany(
{ "routes.codeshare": "" },
{ "$unset": { "routes.$.codeshare": 1 } }
)
For multiple elements within an array, use the filtered positional operator $[<identifier>] which identifies the array elements that match the arrayFilters conditions:
db.airlines.updateMany(
{ "routes.codeshare": "" },
{ "$unset": { "routes.$[element].codeshare" : 1 } },
{ "arrayFilters": [ { "element.codeshare": "" } ] }
)
Try this:
db.airlines.update({ name: "40-Mile Air" },{ $unset: {codeshare : "" }})

Mongoose find returns document instead of specific object in array

When I try to find specific object in array using find({query}) I always get all elements from array.
Activities array stores activities (it would be a thousands of them) as you can see in the following snippet:
This is my collection:
{
"_id" : ObjectId("58407140755324d04db2ce95"),
"owner" : 103429326776572,
"activities" : [
{
"name" : "test1",
"startTime" : ISODate("2016-08-11T17:41:54Z"),
"type" : "te1",
"lat" : 1,
"lon" : 1,
"creator" : 126212904493088,
"coverPhoto" : {
"name" : "test1",
"path" : "c:\\Users\\Francis\\Desktop\\dusk\\public\\coverPhotos\\SJ9tpP6Mx.jpg"
},
"identifier" : "H1g9F6vpGl",
"users" : [
1,
2,
3
],
"hashTags" : [
"some",
"hashtags"
]
},
{
"name" : "test2",
"startTime" : ISODate("2016-08-11T17:41:53Z"),
"type" : "te2",
"lat" : 1,
"lon" : 1,
"creator" : 103312904493090,
"coverPhoto" : {
"name" : "test2",
"path" : "c:\\Users\\Francis\\Desktop\\dusk\\public\\coverPhotos\\Hy8qpvafe.jpg"
},
"identifier" : "rJlU5TvpMx",
"users" : [
1,
2,
3
],
"hashTags" : [
"some",
"hashtags"
]
}
]
}
I need to get for example an activity that has specific identifier.
I tried to use queries like:
1) db.myCollection.find({'activities.identifier' : "rJlU5TvpMx"})
2) db.myCollection.find({'activities' : { $elemMatch : { "identifier" : "rJlU5TvpMx", "creator" : 103312904493090 } })
And all combinations with '' or "" signs
I found above queries at mongodb docs in equal documents schema as mine is.
Can you tell me what am I doing wrong ?
You can try either use single match or multiple match based on your need. This makes use of $elemMatch(projection)
db.myCollection.find({"_id" : ObjectId("58407140755324d04db2ce95")},
{activities: {$elemMatch: { identifier: "rJlU5TvpMx"}}})
db.myCollection.find( {"_id" : ObjectId("58407140755324d04db2ce95")},
{activities: {$elemMatch: {creator : 103312904493090, identifier: "rJlU5TvpMx" }}})
You are looking for the projection object which gets passed as an argument in your query. It allows the return of specific fields from your search rather than the entire document. http://mongoosejs.com/docs/api.html#model_Model.find
I would also suggest looking at the response to this question here: Mongoose Query: Find an element inside an array which makes use of the unwind operator to enter the array as it seems to be relevant to your needs.
In the collection you are searching in, you have just one Document(Object). If you apply method find() to your collection and the query inside matches the value in activities.identifier it will return the only Document(object).
To have a better understanding of what I am talking about check example on mongoose API doc
And query result here.
Try check this out https://docs.mongodb.com/v3.0/reference/operator/projection/elemMatch/#proj._S_elemMatch instead

Number Search with (^)carat in mongoDB does'nt work

unable to search in my mongoDB collection with data-type is Number and carat doesnt seem to work for me
Search query
db.collection.find({mobile : /^9/});
DB collection
{
"_id" : ObjectId(),
"Name" : "Mr.XXX",
"mobile" : NumberLong(9876543210),
"date" : ISODate("2015-07-09T07:21:45.552Z"),
"__v" : 0
}
/* 1 */
{
"_id" : ObjectId(),
"Name" : "Mr.YYY",
"mobile" : NumberLong(887654210),
"__v" : 0
}
But the search result doesnt seem to work for mobile and it works for other dataTypes.
You cannot perform a regex on a number value however, you should change your schema.
Mobile numbers regularly start with a 0 in many countries (UK for example) and do not follow the rules for a strict integer (which NumberLong is) nor are they are a strict size normally as such you should not be storing them as a number type but instead a string type, at which point you can regex on them.
As such, instead of trying to find some weird work around using aggregation or $where, both of which will result in a painful death you should instead change your schema to match the information you are actually entering.
The data is "numeric" so a Regular expression does not work here, as they only work on "strings".
You can use JavaScript evaluation of $where for this, since JavaScript can cast the "type":
db.collection.find(function() { return this.mobile.toString().match(/^9/) })
But that isn't a great idea since $where cannot use an index to match and relys on the coded condition to compare.
If you need to do this sort of matching then your "numeric" data needs to be a "string", or at least have something in the document with the "string" representation:
{
"_id" : ObjectId(),
"Name" : "Mr.XXX",
"mobile" : "9876543210",
"date" : ISODate("2015-07-09T07:21:45.552Z"),
"__v" : 0
}
Then your $regex query works as expected when matching against a "string".
db.collection.find({ "mobile": /^9/ })
As per mongoDB $regex it said that regex regular expression capabilities for pattern matching strings in queries. So first you should convert mobile to String using $substr, assuming your mobile number always 10 digit number.
This aggregation may slow but it satisfied your criteria, check below aggregation query :
db.collectionName.aggregate([
{
"$project": {
"mobileToString": {
"$substr": [
"$mobile",
0,
10
]
},
"Name": 1,
"mobile": 1,
"date": 1,
"__v": 1
}
},
{
"$match": {
"mobileToString": /^9/
}
},
{
"$project": {
"Name": 1,
"mobile": 1,
"date": 1,
"__v": 1
}
}
]).pretty()

Querying nonexistant field in MongoDB

I have an array field called tags in almost every document in a collection. There are a few docs that don't have that field.
If I run db.posts.find({ "some_tag": { $in: tags } }); I'd expect MongoDB to return only the posts that do have "some_tag" in their tag field, and exclude the ones that don't even have the field, but I'm actually getting this error: JavaScript execution failed: ReferenceError: miembros is not defined
Why is that? Can I query my collection this way if some documents don't have that field?
EDIT: Problem fixed. See first comment.
I'd expect MongoDB to return only the posts that do have "some_tag" in their tag
That's what it does, if you query it correctly:
> db.tags.insert({"name" : "john", "tags" : ["tag", "boo"]});
> db.tags.insert({"name" : "mike" });
> db.tags.find({"tags" : "boo" });
{ "_id" : ObjectId("525e53a5e90cc5362ea98842"),
"name" : "john", "tags" : [ "tag", "boo" ] }
or
> db.tags.find({"tags" : {$in : [ "boo"] } });
{ "_id" : ObjectId("525e53a5e90cc5362ea98842"),
"name" : "john", "tags" : [ "tag", "boo" ] }
The problem is that you inverted the $in: You're looking for "posts that do have 'some_tag' in their tag field", but the query { "some_tag": { $in: tags } } looks for documents that have a field some_tag with one of the value given in tags.

Categories

Resources