Querying Embedded array fields in a document in mongodb - mongodb

In mongodb databse, am having problem trying to query a field. My collection users looks like this:
{
"_id" : "sam",
"_password" : "t",
"data" : [
{
"_id" : "hp",
"nodeList" : [{'nodeId' : 1},{'nodeId' : 2},{'nodeId' : 3}],
"edgeList" : [{'edgeId' : 1},{'edgeId' : 2},{'edgeId' : 3}],
"options" : {
"edgeColor" : "blue",
"nodeColor" : "black"
}
},
{
"_id" : "tt",
"nodeList" : [{'nodeId' : 1},{'nodeId' : 2},{'nodeId' : 3}],
"edgeList" : [{'edgeId' : 1},{'edgeId' : 2},{'edgeId' : 3}],
"options" : {
"edgeColor" : "blue",
"nodeColor" : "black"
}
}
]},
{
"_id" : "bob",
"_password" : "w",
"data" : [
{
"_id" : "hello",
"nodeList" : [{'nodeId' : 1},{'nodeId' : 2},{'nodeId' : 3}],
"edgeList" : [{'edgeId' : 1},{'edgeId' : 2},{'edgeId' : 3}],
"options" : {
"edgeColor" : "blue",
"nodeColor" : "black"
}
},
{
"_id" : "world",
"nodeList" : [{'nodeId' : 1},{'nodeId' : 2},{'nodeId' : 3}],
"edgeList" : [{'edgeId' : 1},{'edgeId' : 2},{'edgeId' : 3}],
"options" : {
"edgeColor" : "blue",
"nodeColor" : "black"
}
}
]
}
I need to retrieve the nodeList/edgeList from this and also change the edgeColor in options given a particular _id. For eg : _ id : "bob".
I tried a few things but could not get the output.
db.users.find({ '_id': 'sam' , "users.data._id" : "hp"}, {})
db.users.findOneAndUpdate({"_id":"sam", "users.data._id": "hp"},{$addToSet:{"users.data.nodeList":{"nodeId":1,"nodeName":"Bellanduru", "lat":43.12, "long":33.43,"stock":3}}})
Please tell me what's wrong.

you declare your collection name with this db.users in selected db
and you select users collection so not necessary specify in query
for example this "users.data._id" replace with this "data._id"
replace your querys like this
db.users.find({ '_id': 'sam' , "data._id" : "hp"}, {})
db.users.findOneAndUpdate({"_id":"sam", "data._id": "hp"},{$addToSet:{"data.nodeList":{"nodeId":1,"nodeName":"Bellanduru", "lat":43.12, "long":33.43,"stock":3}}})

Related

$lookup aggregation failed to display array value

I'm working with MongoDB and I've 2 collections.
data collection ["user-profile"]
{
"_id" : ObjectId("60650e6fc4b4603e1e78bb23"),
"firstName" : "Luthfan",
"lastName" : "Difiesa",
"mobile" : "86742633497",
"gender" : "male",
"createdOn" : ISODate("2021-04-22T05:26:07.428+0000"),
"updatedOn" : ISODate("2021-04-22T05:26:55.218+0000")
}
data collection ["user-wishlist"]
{
"_id" : ObjectId("60650e7a1a4a817a1dd0a29c"),
"userId" : "86742633497",
"contents" : [
{
"_id" : ObjectId("5ef9d2da228f840bbd41649c"),
"name" : "Kelas 11"
}
]
}
expected output:
{
"_id" : ObjectId("60650e6fc4b4603e1e78bb23"),
"firstName" : "Luthfan",
"lastName" : "Difiesa",
"mobile" : "86742633497",
"gender" : "male",
"contents" : [
{
"_id" : ObjectId("5ef9d2da228f840bbd41649c"),
"name" : "Kelas 11"
}
]
}
Here's the query:
db.getCollection("user-profile").aggregate(
[
{
"$lookup" : {
"from" : "user-wishlist",
"localField" : "mobile",
"foreignField" : "userId",
"as" : "contents"
}
}
],
{
"allowDiskUse" : false
}
);
But the result is like this:
{
"_id" : ObjectId("60650e6fc4b4603e1e78bb23"),
"firstName" : "Luthfan",
"lastName" : "Difiesa",
"mobile" : "86742633497",
"gender" : "male",
"contents" : [
]
}
is't because of collection name using special character or type data from foreign or localField? thank u...
Your query looks good, just need add a stage after lookup to achieve your desire result,
{
$addFields: {
contents: {
$arrayElemAt: ["$contents.contents", 0]
}
}
}
Playground

I Want add if data in element array not exists

I have this data in database.
{
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b"),
"name" : "Jhones Crows",
"hobbies" : [
{
"name" : "swim",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b")
},
{
"name" : "run",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7c")
}
]
}
And I try to add data into hobbies if data in hobbies not exist. I try this :
db.getCollection('milo').update(
{'_id' : ObjectId("5a6ef287370ff5dc3d6fda7b"), 'hobbies.name' : 'sport'},
{ $addToSet : { 'hobbies' : {
'name' : 'sport',
}}
},
{upsert : true}
)
And I want data result like this :
{
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b"),
"name" : "Jhones Crows",
"hobbies" : [
{
"name" : "swim",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7b")
},
{
"name" : "run",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7c")
},
{
"name" : "sport",
"_id" : ObjectId("5a6ef287370ff5dc3d6fda7a")
}
]
}
so suppose the value of sport is not in hoobies.name. will add a new name object in the hobbies. but if there is not change anything

MongoDB $lookup on array of object

I have 2 collections structured as below. I have tried $lookup to get the result but I am not getting any result because of my local and foreign fields are in array of object.
Below is my structure:
{
"_id" : ObjectId("5795a3531d3f3afc19caefef"),
"name" : "category1",
"updatedAt" : "1469431592786",
"resources" : [
{
"_id" : ObjectId("5791be003fa3bedc15d3adde"),
"title" : "resource1",
"availability" : false
},
{
"_id" : ObjectId("5795a3771d3f3afc19caeff0"),
"title" : "resource2",
"availability" : true
}
]
}
Above "categories" schema have resources array of object. this resource _id is stored in bookings collection in following way:
"booking":
{
"_id" : ObjectId("57960aa8000ca7a46b7ef683"),
"name" : "1469491200000",
"__v" : 0,
"schedule" : [
{
"resourceId" : ObjectId("5791be003fa3bedc15d3adde"),
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "grofep",
"_id" : ObjectId("57960aa8f9f9951c1fc923b1")
},
{
"resourceId" : ObjectId("5791be003fa3bedc15d3bddz"),
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "mr3",
"_id" : ObjectId("57960aa8f9f9951c1fc923b2")
},
{
"resourceId" : ObjectId("5791be003fa3bedc15d3adde"),
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "grofep23",
"_id" : ObjectId("57960aa8f9f9951c1fc923b3")
}
]
}
Now I want to get all the schedule of booking collection with their resource information.I want to fetch resources from categories table on the basis of booking schedule.
Desired output:
[
{
"name" : "1469491200000",
"resourceId" : ObjectId("5791be003fa3bedc15d3adde"),
"resourceTitle":"title",
"availability":false,
"bookings": [
{
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "grofep",
"_id" : ObjectId("57960aa8f9f9951c1fc923b1")
},
{
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "grofep23",
"_id" : ObjectId("57960aa8f9f9951c1fc923b3")
}
]
},
{
"name" : "1469491200000",
"resourceId" : ObjectId("5791be003fa3bedc15d3bddz"),
"resourceTitle":"mr3",
"availability":false,
"bookings": [
{
"userId" : ObjectId("5791be003fa3bedc15d3adcve"),
"title" : "mr3",
"_id" : ObjectId("57960aa8f9f9951c1fc923b2")
}
]
}
]
Help me to get this desired result.
Thanks.

mongo query doesn't work with $ in field name

Command to get raw_data:
db.raw_data.find({'cat':'like'},
{'properties':1}).limit(1).pretty()
data:
{
"_id" : ObjectId("5656b9a0c2492dec3442da52"),
"properties" : {
"subcategory" : "49",
"$carrier" : "Vodafone India",
"$radio" : "HSDPA",
"$region" : "Gujarat",
"$screen_width" : 375,
"$wifi" : false,
"mp_lib" : "iphone",
"product_unlike_flag" : false,
"mp_device_model" : "iPhone7,2",
"user_id" : "4",
"$city" : "Ahmedabad",
"$manufacturer" : "Apple",
"$os" : "iPhone OS",
"brand" : "AO",
"gender" : "Men",
"mp_country_code" : "IN",
"time" : 1445376786,
"$app_release" : "0.8.0",
"$lib_version" : "2.8.2",
"$model" : "iPhone7,2",
"$screen_height" : 667,
"category" : "48",
"$app_version" : "0.8.0",
"$os_version" : "9.0.2",
"itemcode" : "174",
"source" : "Product"
}
}
I want to extract user_id and city from this data.
I tried these Command :
Command1 :
db.raw_data.aggregate([{$group : {_id :{'user_id': "$properties.user_id","cat":"$cat","brand":"$properties.brand" } ,"num_tutorial" :{$sum:1}}} ,{ $project : {properties.$city : 1 } } ])
Command2:
db.raw_data.find({'cat':'like'},{'properties.$city':1})
which gave me an error:
Error: error: {
"$err" : "Can't canonicalize query: BadValue Positional projection 'properties.$city' does not match the query document.",
"code" : 17287
}
Is there any way/query so I can extract user-city relations from this data.
In suck cases mongodb recommends to use unicode equivalent of '$'. This method is called $ sign escaping.
So your find query will look like following:
db.raw_data.find({'cat':'like'},{'properties.\uff04city':1})
Hope this helps :)
Result:
> db.collection.find({},{'properties.\uff04city':1})
{ "_id" : ObjectId("5656e09ccb0a925b3d5d16f2"), "properties" : { "$city" : "value" } }
{ "_id" : ObjectId("5656e502cb0a925b3d5d16f3"), "properties" : { "$city" : "value" } }

Get document based on multiple criteria of embedded collection

I have the following document, I need to search for multiple items from the embedded collection"items".
Here's an example of a single SKU
db.sku.findOne()
{
"_id" : NumberLong(1192),
"description" : "Uploaded via CSV",
"items" : [
{
"_id" : NumberLong(2),
"category" : DBRef("category", NumberLong(1)),
"description" : "840 tag visual",
"name" : "840 Visual Mini Round",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(7),
"category" : DBRef("category", NumberLong(2)),
"description" : "Maxi",
"name" : "Maxi",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(11),
"category" : DBRef("category", NumberLong(3)),
"description" : "Button",
"name" : "Button",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(16),
"category" : DBRef("category", NumberLong(4)),
"customizationFields" : [
{
"_class" : "CustomizationField",
"_id" : NumberLong(1),
"displayText" : "Custom Print 1",
"fieldName" : "customPrint1",
"listOrder" : 1,
"maxInputLength" : 12,
"required" : false,
"version" : NumberLong(0)
},
{
"_class" : "CustomizationField",
"_id" : NumberLong(2),
"displayText" : "Custom Print 2",
"fieldName" : "customPrint2",
"listOrder" : 2,
"maxInputLength" : 17,
"required" : false,
"version" : NumberLong(0)
}
],
"description" : "2 custom lines of farm print",
"name" : "Custom 2",
"version" : NumberLong(2)
},
{
"_id" : NumberLong(20),
"category" : DBRef("category", NumberLong(5)),
"description" : "Color Red",
"name" : "Red",
"version" : NumberLong(0)
}
],
"skuCode" : "NF-USDA-XC2/SM-BC-R",
"version" : 0,
"webCowOptions" : "840miniwithcust2"
}
There are repeat items.id throughout the embedded collection. Each Sku is made up of multiple items, all combinations are unique, but one item will be part of many Skus.
I'm struggling with the query structure to get what I'm looking for.
Here are a few things I have tried:
db.sku.find({'items._id':2},{'items._id':7})
That one only returns items with the id of 7
db.sku.find({items:{$all:[{_id:5}]}})
That one doesn't return anything, but it came up when looking for solutions. I found about it in the MongoDB manual
Here's an example of a expected result:
sku:{ "_id" : NumberLong(1013),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(2) } ] },
sku:
{ "_id" : NumberLong(1014),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(2) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(24) } ] },
sku:
{ "_id" : NumberLong(1015),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(2) },
{ "_id" :NumberLong(5) } ] }
Each Sku that comes back has both a item of id:7, and id:2, with any other items they have.
To further clarify, my purpose is to determine how many remaining combinations exist after entering the first couple of items.
Basically a customer will start specifying items, and we'll weed it down to the remaining valid combinations. So Sku.items[0].id=5 can only be combined with items[1].id=7 or items[1].id=10 …. Then items[1].id=7 can only be combined with items[2].id=20 … and so forth
The goal was to simplify my rules for purchase, and drive it all from the Sku codes. I don't know if I dug a deeper hole instead.
Thank you,
On the part of extracting the sku with item IDs 2 and 7, when I recall correctly, you have to use $elemMatch:
db.sku.find({'items' :{ '$all' :[{ '$elemMatch':{ '_id' : 2 }},{'$elemMatch': { '_id' : 7 }}]}} )
which selects all sku where there is each an item with _id 2 and 7.
You can use aggregation pipelines
db.sku.aggregate([
{"$unwind": "$sku.items"},
{"$group": {"_id": "$_id", "items": {"$addToSet":{"_id": "$items._id"}}}},
{"$match": {"items._id": {$all:[2,7]}}}
])