Mongodb native driver chain queries - javascript

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.

Related

How to update specific data in array in MongoDB?

{
"_id":{"$oid":"5f5287db8c4dbe22383eca58"},
"__v":0,
"createdAt":{"$date":"2020-09-12T11:35:45.965Z"},
"data":["Buy RAM","Money buys freedom"],
"updatedAt":{"$date":"2020-09-12T11:38:10.637Z"}
}
I want to update the first element in this data array field as Buy SSD.
How can I do it using NodeJS?
db.collection.findOneAndUpdate({
"_id.$oid": "5f5287db8c4dbe22383eca58",
data: "Buy RAM"
}, {
$set: {
"data.$" "Buy SSD"
}
})
This query updates the first element in the data array inside the document that matches "_id.$oid": "5f5287db8c4dbe22383eca58", using $ positional identifier and sets it to the new value.
For more Array Update Operators in mongodb, here is a reference: mongodb manual
You can use filtered positional operator
db.collectionName.updateOne(
{
"_id.$oid": "5f5287db8c4dbe22383eca58"
},
{
$set: {
"data.$[element]": "Buy SSD"
}
},
{
{ arrayFilters: [ { element: "Buy Ram" } ] }
})
Caution: It will update all array element matching the text. In this case, "Buy Ram"
You can use str.replace()
var product =
[{
"_id":{"$oid":"5f5287db8c4dbe22383eca58"},
"__v":"0",
"createdAt":{"$date":"2020-09-12T11:35:45.965Z"},
"data":["Buy RAM","Money buys freedom"],
"updatedAt":{"$date":"2020-09-12T11:38:10.637Z"}
}]
var new_product = JSON.stringify(product).replace("Buy RAM", "Something");
console.log(new_product);
UpdateOne -> Updates a single Document:
db.collection.updateOne(filter, update, options)
You will probably gonna filter using the _id field, and use $set to update the specific field.
Use the dot-notation to access and set fields deep inside objects, without affecting the other properties of those objects.
you want to update the 1st array entry in "data", and array keys are 0 indexed - that's the key 0.
so the query will look something like that:
db.collection.update(
{ _id: { "$oid": "56476e04e5f19d86ece5b81d"}, // probb ObjectId Instance
{ $set:
{
"data.0": "Buy SSD" // Using dot-notation
}
}
)
for more advanced use, you can use the MongoDB's positional operator $ without explicitly specifying the position of the element in the array.
The positional operator allows you to use a condition like this:
{"Order.name": "test"}
and then reference the found array entry like so:
{"Order.$ // <- the dollar represents the first matching array key index
Example:
/* DATA
{
"_id" : "43434",
"Order" : [
{"name" : "test", "items" : ["", "new_value", "" ]},
{"name" : "test2", "items" : ["", "", "" ]}
]
}
*/
db.collection.update(
{ _id: "43434", "Order.name": "test2"},
{ $set:
{
"Order.$.items.1": "new_value2" // positional operator & dot-notation.
}
}
)
>>> db.collection.find()
{
"_id" : "43434",
"Order" : [
{"name" : "test", "items" : ["", "new_value", "" ]},
{"name" : "test2", "items" : ["", "new_value2", "" ]}
]
}

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

Matching field by omitting spaces - MongoDB

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.

How to make MongoDB find nested json return as an array?

I have this data:
{
"_id" : ObjectId("5461e16ee7caf96f8f3584a2"),
"num_marcacao" : "100",
"sexo" : "Fêmea",
"idade" : "20",
"bigdata" : {
"abortos" : [
{
"data_aborto" : "2014-11-11",
"causa_aborto" : "Aborto causa 1"
},
{
"data_aborto" : "2014-09-01",
"causa_aborto" : "Aborto causa 2"
}
],
"crias" : [
ObjectId("5461e16ee7caf96f8f3584a2")
]
}
}
{
"_id" : ObjectId("5461e1cae7caf96f8f3584a4"),
"num_marcacao" : "200",
"sexo" : "Fêmea",
"bigdata" : {
"crias" : [
ObjectId("5461e1f3e7caf96f8f3584a5"),
ObjectId("5461e760e7caf96f8f3584a6")
]
}
}
Using the following distinct function I get one result
db.animal.distinct('_id', {'bigdata.crias':{$exists:true}}
Result:
{
"0" : ObjectId("5461e16ee7caf96f8f3584a2"),
"1" : ObjectId("5461e1cae7caf96f8f3584a4")
}
Now I want to get the array that is in bigdata.crias like the result of the distinct query.
I'm trying to do like this:
db.animal.find(
{
$and: [
{'num_marcacao': '200'},
{'bigdata.crias':{$exists: true}}
]
},
{
'bigdata.crias': true,
'_id': false
}
)
But the result is not like the one I need. This is what it's returning:
{
"bigdata" : {
"crias" : [
ObjectId("5461e1f3e7caf96f8f3584a5"),
ObjectId("5461e760e7caf96f8f3584a6")
]
}
}
And I need
{
"0" : ObjectId("5461e1f3e7caf96f8f3584a5"),
"1" : ObjectId("5461e760e7caf96f8f3584a6")
}
Anyhow. MongoDB does not generally do this from either the .find() or .aggregate() methods or anything general around them. Only the .distinct() method invokes a special form where the result given is "truly" just an array of the specified "key" to be distinct on.
You can always "inspect" the object returned and just use the array element in the structure. You can also specify a "query" argument to the .distinct() command method in the first place:
db.collection.distinct(
"bigdata.crias",
{
"bigdata.crias": { "$exists": true },
"num_marcacao": "200"
}
);
Where you also see your $and argument is redundant. All MongoDB query arguments are an "and" implementation by default. You don't need this unless you are specifying "more than one" condition on the same "field name". That would result in an invalid object by breaking the basic "hash/map" "unique key" rule, and which is why and "array" is used for this form to keep it valid.

Categories

Resources