Query on array of array object in mongodb - arrays

Following is my product collection in mongodb..
{
"_id" : ObjectId("56d42389db70393cd9f47c22"),
"sku" : "KNITCHURI-BLACK",
"options" : [
{
"sku" : "KNITCHURI-BLACK-M",
"stores" : [
{
"code" : "6",
"quantity" : 0
},
{
"code" : "10",
"quantity" : 26
}
],
"ean_code" : "2709502",
"size" : "M"
},
{
"sku" : "KNITCHURI-BLACK-S"
"stores" : [
{
"code" : "6",
"quantity" : 0
},
{
"code" : "10",
"quantity" : 30
}
],
"size" : "S"
}
]
}
want query on where { 'options.stores.code' : '6' } and { 'options.stores.quantity' : { $gt : 0 } }, How i query on this collection then i got response? Kindly help on this issue..

Here is the two approaches to get documents in Mongoose.
You can change the Mongo query if required as given in the various answers. I have just used your approach for Mongo query.
Approach 1 - Using cursor - Recommended Approach
Approach 2 - Using Query
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Schema = mongoose.Schema, ObjectId = Schema.ObjectId;
var Store = new Schema({
code : String,
quantity : Number
});
var Option = new Schema({
sku : String,
stores : [ Store ],
ean_code : String,
size : String
});
var productSchema = new Schema({
_id : ObjectId,
sku : String,
options : [ Option ]
});
var Product = mongoose.model('product', productSchema, 'product');
console.log("Cursor Approach #1");
var cursor = Product.find({
'options.stores' : {
$elemMatch : {
code : '6',
quantity : {
$gt : 0
}
}
}
}).cursor();
console.log("Curosr Results***************************************");
cursor.on('data', function(doc) {
console.log("Getting doc using cursor ==========>" + JSON.stringify(doc));
});
cursor.on('close', function() {
console.log("close the cursor");
});
console.log("Query Approach #2");
var query = Product.find({
'options.stores' : {
$elemMatch : {
code : '6',
quantity : {
$gt : 0
}
}
}
});
console.log("Query Results***************************************");
query.exec(function(err, doc) {
if (err) {
console.log(err);
}
console.log("Getting doc using query ==========>" + JSON.stringify(doc));
});

I think you need to unwind options
db.product.aggregate( [
{ $unwind: "$options" }
{ $match: { 'options.stores.code' : '6','options.stores.quantity' : { $gt : 0 }}
] )

As far as I understand the question, you want to find a products that are in stock in stores with code 6. The following query does that:
db.collection.find({"options.stores" : {$elemMatch: {"code" : "6", "quantity" : {$gt : 0}}}});

Related

Update documents nested multiple levels in an array

I have this JSON structure in MongoDb and want to update changing a specific value of a particular item in a nested array. I would like to change the key targetAreaId from USER_MESSAGE to VISUAL_MESSAGE.
{
"_id" : "5cde9f482f2d5b924f492da2",
"scenario" : "SCENARIOX",
"mediaType" : "VISUAL",
"opCon" : "NORMAL",
"stepConfigs" : [
{
"stepType" : "STEPX",
"enabled" : true,
"configs" : [
{
"contentTemplateId" : "5cde9f472f2d5b924f492973",
"scope" : "STANDARD",
"key" : "CONTENT"
},
{
"priorityId" : "5cde9f472f2d5b924f49224f",
"scope" : "STANDARD",
"key" : "PRIORITY"
},
{
"targetAreaId" : "USER_MESSAGE",
"scope" : "STANDARD",
"key" : "TARGET_AREA"
}
],
"description" : "XPTO"
}
],
"scope" : "STANDARD" }
How can I do it in the same time?
EDIT
I am trying this way:
var cursor = db.getCollection('CollectionX').find({
"scenario": "SCENARIOX",
"stepConfigs.stepType": "STEPX",
"stepConfigs.configs.key": "TARGET_AREA"
});
if (cursor.hasNext()) {
var doc = cursor.next();
doc.stepConfigs.find(function(v,i) {
if (v.stepType == "STEPX") {
doc.stepConfigs[i].configs.find(function(w,j) {
if (w.key == "TARGET_AREA") {
var result = db.getCollection('CollectionX').update(
{ "_id" : doc._id },
{ "$set" : { doc.stepConfigs[i].configs[j].targetAreaId: "VISUAL_MESSAGE" }}
);
}
});
};
});
} else {
print("Step does not exist");
}
But the error below is occurring:
Error: Line 15: Unexpected token .
I don't think that's possible.
You can update the specific element you want using this query:
db.test_array.updateOne({}, {
$set: {
"stepConfigs.$[firstArray].configs.$[secondArray].targetAreaId": "VISUAL_MESSAGE"
}
}, {
arrayFilters: [{
"firstArray.stepType": "STEPX"
}, {
"secondArray.targetAreaId": "USER_MESSAGE"
}]
})
But pushing in the same array at the same time does render this (this was for the original model, but it's still the same problem, you can't $set and $push in the same array this way):
> db.test_array.updateOne({"step.type":"B"},{$push:{"step.$.configs":{"className":"something"}}, $set:{"step.$.configs.$[secondArray].targetAreaId":"TA-1"}},{arrayFilters:[{"secondArray.targetAreaId":"TA-2"}]})
2019-09-06T13:53:44.783+0200 E QUERY [js] WriteError: Updating the path 'step.$.configs.$[secondArray].targetAreaId' would create a conflict at 'step.$.configs' :

Update an element of an Array in a Document in MongoDB with Mongoose

I have a MongoDB database whith a collection with this structure:
{
"_id" : ObjectId("5b670eefe94672265ca59428"),
"duration" : {
"start" : ISODate("2018-09-01T00:00:00.000Z"),
"end" : ISODate("2018-09-01T00:00:00.000Z")
},
"title" : "Example title.",
"description" : "<p>Hi example!</p>",
"slug" : "title",
"insertDate" : ISODate("2018-08-05T14:51:27.194Z"),
"webData" : [
{
"_id" : ObjectId("5bb1f082931c536950ade361"),
"webCode" : "be_mx",
"categories" : [
{
"_id" : ObjectId("3sdf43f34543et35tret435"),
"name" : "Category 1",
"webCode" : "be_mx",
"slug" : "category-1"
},{
"_id" : ObjectId("3sdf43f34543et35tretert"),
"name" : "Category 2",
"webCode" : "be_mx",
"slug" : "category-2"
}
]
}
],
"__v" : 6,
"lastEditionDate" : ISODate("2018-10-01T10:01:38.889Z")
}
I want to update all documents from this collection that has a categorie with a _id = "3sdf43f34543et35tret435" (in this example the "Category 1"), and I want to update this element category setting, for example, the slug to "category-3".
I tried to do that with this code:
Collection.update({
"webData.categories": {
$elemMatch: {
_id: ObjectId("3sdf43f34543et35tret435")
}
}
}, {
$set: {
webData: {
"categories.$.slug": "category-3"
}
}
}, {
multi: true
}, (err, res) => {
if (err) { console.log(err); }
console.log(res);
});
When I execute that, all the documents that have this category are edited but it's wrong because all the related categories are deleted.
Can you help me with this operation?
Thank you!
EDITED:
When I execute in my DB this query:
db.getCollection("scholarships").update({},
{ '$set': { 'webData.[].categories.$[category].slug': "nana" } },
{ multi: true, arrayFilters: [{ 'category._id': ObjectId("5b719d821f3f1131ec4524f6") }] })
Using in this time an arrayFilter, I receive this error:
The path 'webData.[].categories' must exist in the document in order to apply array updates."

How to push object without filed name in mongodb with nodejs

This is my Schema design
mongoose.Schema({
traffic_countries:String,
company_details:String,
campaigns:[{
_campaignid : mongoose.Schema.Types.ObjectId,
}],
impressions:[{
country:String,
_campaignid :mongoose.Schema.Types.ObjectId
}],
payments:[],
budget:String })
What i want to do
I want to push the object below in the payments array the code that i am using for this purpose is given below the object
{
"id" : "PAY-52L98986JB4797714LN73QTY",
"intent" : "sale",
"state" : "created",
"payer" : {
"payment_method" : "paypal"
},
"transactions" : [
{
"amount" : {
"total" : "12.00",
"currency" : "USD"
},
"description" : "",
},
"related_resources" : [ ]
}
],
"create_time" : "2018-08-24T07:48:30Z",
"links" : [
{
"rel" : "execute",
"method" : "POST"
}
],
"httpStatusCode" : 201
}
The Code I am using for this purpose
The above object is stored in the transaction variable that i am getting from paypal api and pushing in the payments array
var newPayment = {
$push:{
payments:{
transaction
}
}
}
Advertiser.updateOne({_id:req.user.id},newPayment,function(err,rec){
if(err) throw err;
})
The objects that are stored in mongodb are like
payments:[
{ transaction:{object} },
{ transaction:{object} },
{ transaction:{object} }
]
But i want to store objects like
payments:[
{object},
{object},
{object}
]
After a lot of time waste i found out the answer to this problem by myself i only need to remove the extra brackets in the push query
Instead of this
var newPayment = {
$push:{
payments:{
transaction
}
}
}
I needed that
var newPayment = {
$push:{
payments:transaction
}
}

update nested array element value in node js mongoDB [duplicate]

This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 6 years ago.
Hi i am new in nodejs i need to update a value in nested array using _id of document my database document is look like this..
"complaints" : [
{
"complaint" : "head light is not working",
"complaintid" : ObjectId("57205219a56d2b8c0f9274a4"),
"_id" : ObjectId("57454c9249218eb40c1c0d1f"),
"labour" : 350,
"partCost" : 0,
"part" : [
{
"id" : ObjectId("56f12eaab915bd9800272ed7"),
"estimate" : 450,
"partname" : "clutch",
"_id" : ObjectId("57454cef49218eb40c1c0d25"),
"quantity" : 0,
"qrcodes" : []
},
{
"id" : ObjectId("56f12eaab915bd9800272ed7"),
"estimate" : 450,
"partname" : "rear tyre",
"_id" : ObjectId("57454cef49218eb40c1c0d24"),
"quantity" : 0,
"qrcodes" : []
}
],
"acceptance" : true,
"inspection" : false,
"color" : "#8929A9",
"status" : "APPROVED",
"estimate" : 1200,
"solution" : "HEAD LIGHT CHANGE",
"problems" : "HEAD LIGHT IS NOT WORKING"
},
i need to update quantity value of part array exist inside the part array using _id of part array
i am trying this but its not working what should i do for update this value...
var partdata = req.payload.parts;
for(var k = 0; k< partdata.length ; k++ ){
CPS.update({
'complaints.part._id' : partdata[k].partid
}, {
"$inc" : {
'complaints.part.$.quantity' : partdata[k].quantity
}
}).exec
(function(err,temp) {
if(err){
res(err).code(500);
}else{
console.log(temp);
}
});
}
MongoDB doesn't support matching into more than one level of an array.
Consider altering your document model so each document represents an
operation, with information common to a set of operations duplicated
in the operation documents.
Following is not the solution for your case.
But in-case you know the index then you could do something like this:
Assume a sample document like:
{
"_id" : ObjectId("57454c9249218eb40c1c0d1f"),
"part" : [{ "quantity" : 111 }, { "quantity" : 222 }]
}
Then this query should work.
db.test.update({ "_id" : ObjectId("57454c9249218eb40c1c0d1f") }, { "$set" : { "part.1.quantity" : 999 } })
Document will get modified as follows :
{
"_id" : ObjectId("57454c9249218eb40c1c0d1f"),
"array" : [{ "quantity" : 222 }, { "quantity" : 999 }]
}
Update: You can try following way of doing the update. But its not recommended way of doing probably you need to restructure your schema.
db.test.aggregate([
{ "$unwind": "$complaints" },
{ "$unwind": "$complaints.part" },
{ "$project":
{
_id: "$complaints.part._id",
partqty: "$complaints.part.quantity"
}
},
]);
This should return as follows:
{
"_id" : ObjectId("57454cef49218eb40c1c0d25"),
"partqty" : 111
}
{
"_id" : ObjectId("57454cef49218eb40c1c0d24"),
"partqty" : 222
}
Now you can use this information to update, e.g
var cur = db.test.aggregate([
{ "$unwind": "$complaints" },
{ "$unwind": "$complaints.part" },
{ "$project":
{
_id: "$complaints.part._id",
partqty: "$complaints.part.quantity"
}
},
]);
while (cur.hasNext()) {
var doc = cur.next();
//Note the index should be know again :|
db.test.update({ "complaints.part._id": ObjectId("57454cef49218eb40c1c0d25") },
{ "$set": { "complaints.$.part.1.quantity": 55 }},
{ "multi": true})
}

How to query the firebase database to fetch specific data?

{
"todo" : {
"Kujbghnkj04t56-" : {
"id" : 1,
"tags" : [ {
"name" : "Italy"
}, {
"name" : "Australia"
} ],
"username" : "ABC"
},
"oPikoieew9oR-" : {
"id" : 2,
"tags" : [ {
"name" : "Switzerland"
} ],
"username" : "XYZ"
}
}
}
I am trying to search in Firebase according to tags name. My code is:
var tagRef = new Firebase(FURL+'/todo');
var tagCollection = $firebaseArray(tagRef);
tagCollection.$ref().orderByChild("tags").equalTo("Australia").once("value", function(dataSnapshot){
// code
});`
How can I get the snapshot of all data containing tag name as "Australia"

Resources