I have data something like below:
{
"_id": "60708607143b058e101fc189",
"orders": {
"userID": "606eaa5cf67ac70cfa347fcd",
"order": [
{
"productIDs": [ "606f1f37006513258c8b59b9" ],
"vendorID": "60641cf597aed2a9a2971a3f",
"id": "60708607143b058e101fc18a"
},
{
"productIDs": [ "606f1fec006513258c8b59ba", "606f2bb2006513258c8b59bd" ],
"vendorID": "60642991015028ba0a6ce72c",
"id": "60708607143b058e101fc18b"
}
]
},
}
Is there a way to find any given vendorID in this record using nodejs and mongoose?
If you are logged in as a vendor, then you can send the vendor_id in the body of the request. To filter all orders associated to that particular vendor, you can try this:
Model.find({"orders.order":
{
"$elemMatch": {
"vendorID": req.body.vendor_id
}
}
});
I am very new to MongoDB and I need to do a somewhat complex Update operation on my collection.
I have this kind of collection:
[
{
"Id": 1,
"extension": [
{
"keyName": "Name",
"value": "Bob"
},
{
"keyAge": "Age",
"value": 20
}
]
},
{
"Id": 2,
"extension": [
{
"keyName": "Name",
"value": "Sam"
},
{
"key": "Name",
"value": "Sam"
}
]
},
{
"Id": 3,
"extension": [
{
"keyName": "Age",
"value": 25
},
{
"key": "Age",
"value": 25
}
]
},
{
"Id": 4
}
]
I would like to update any items in the extension array of all documents
so that when an item is found with a key property, to rename it keyAge.
Here is the expected result:
[
{
"Id": 1,
"extension": [
{
"keyName": "Name",
"value": "Bob"
},
{
"keyAge": "Age",
"value": 20
}
]
},
{
"Id": 2,
"extension": [
{
"keyName": "Name",
"value": "Sam"
},
{
"keyAge": "Name",
"value": "Sam"
}
]
},
{
"Id": 3,
"extension": [
{
"keyName": "Age",
"value": 25
},
{
"keyAge": "Age",
"value": 25
}
]
},
{
"Id": 4
}
]
I tried to use $rename in a similar way to this question:
MongoDB rename database field within array
but I get the same error $rename source may not be dynamic array
I think this solution might also apply to me, I tried using it but it's not updating anything on my side, so I guess I cannot understand how to apply that answer to me...
https://stackoverflow.com/a/49193743/215553
Thanks for the help!
I tried to use $rename in a similar way to this question: MongoDB rename database field within array but I get the same error $rename source may not be dynamic array
There is a note in $rename:
$rename does not work if these fields are in array elements.
You can try update with aggregation pipeline starting from MongoDB 4.2,
check condition id key field is exists
$map to iterate loop of extension array
$map to iterate loop of array that is converted from extension object to array in key-value format
$cond check condition if k is key then return keyAge otherwise return current
$arrayToObject back to convert key-value array return from above map to object original format
db.collection.update(
{ "extension.key": { $exists: true } },
[{
$set: {
extension: {
$map: {
input: "$extension",
in: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$$this" },
in: {
k: {
$cond: [
{ $eq: ["$$this.k", "key"] }, // check "key" field name
"keyAge", // update new name "keyAge"
"$$this.k"
]
},
v: "$$this.v"
}
}
}
}
}
}
}
}],
{ multi: true }
)
Playground
Question : How to Rename or add new key for existing array object key?
Answer : Inside projection of mongodb query we have map property which will resolve this.
Solution Example :
{
parents: {
$map: {
input: "$parents",
as: "parent",
in: {
caaUserId: "$$parent._id",
email: "$$parent.email",
countryCode: "$$parent.countryCode",
mobile: "$$parent.mobile",
reportType : "single"
}
}
}
}
In this example if we want to rename $parent._id as caaUserId in parents array for each Element.
Then we can use map and define caaUserId like $$parent._id. This whole code will work in mongoose projection of Query.
It should return following :
{
"parents" : [
{
"caaUserId" : "62d17fa164057000149e283f",
"email" : "john.doe#hotmail.com",
"countryCode" : 91,
"mobile": 9876543210,
"reportType":"single",
},
{
"caaUserId" : "6195d50f15ae2b001293c486",
"email" : "akka.ash#hotmail.com",
"countryCode" : 91,
"mobile": 9876543211,
"reportType":"multi",
},
]
}
This is something that works in your case. Might not be the most readable though.
import json
data = json.loads(strdata)
for entry in data:
if 'extension' in entry:
for x in entry['extension']:
for k, v in x.items():
if k == 'key':
x['keyAge'] = x.pop(k)
I have such document:
{
"name": "FirstObj",
"attributes": {
"my_attributes/601890": {
"value": "Hellow World",
"id": "my_attributes/601890",
"name": "TEstAttr",
"myAttribute": "my_attributes/601890",
"_class": "MyAttributeValue"
}
},
"_class": "MyObj"
}
I cannot write AQL query which unsets "myAttribute": "my_attributes/601890". So i want to get such final document:
{
"name": "FirstObj",
"attributes": {
"my_attributes/601890": {
"value": "Hellow World",
"id": "my_attributes/601890",
"name": "TEstAttr",
"_class": "MyAttributeValue"
}
},
"_class": "MyObj"
}
Note, field attributes is object like key-value.(my_attributes/601890: {}) The field will be huge in the future
You can try to set the value to null and set the options keepNull to false to remove the field during the update.
For item in collection
UPDATE item
WITH {attributes: {"my_attributes/601890": {myAttribute: null}} }
IN collection
OPTIONS { keepNull: false }
How can I get only one item when querying an array on CloudantDB?
Example document :
"category": {
"sub_category": [
{
"category_id": "127"
},
{
"category_id": "128"
}
],
}
query :
{
"selector": {
"sub_category": {
"$elemMatch": {
"category_id": "127"
}
}
}
}
wish result document:
"category": {
"sub_category": [
{
"category_id": "127"
}
],
}
You can't do that with Mango queries. You can accomplish something similar with a combination of a traditional view, and a show function.
My data:
{
"rootElement": {
"names": {
"name": [
"Haseb",
"Anil",
"Ajinkya",
{
"city": "mumbai",
"state": "maharashtra",
"job": {
"second": "bosch",
"first": "infosys"
}
}
]
},
"places": {
"place": {
"origin": "INDIA",
"current": "GERMANY"
}
}
}
}
I created a hash index on job field with the API:
http://localhost:8529/_db/_api/index?collection=Metadata
{
"type": "hash",
"fields": [
"rootElement.names.name[*].jobs"
]
}
And I make the search query with the API:
http://localhost:8529/_db/_api/simple/by-example
{
"collection": "Metadata",
"example": {
"rootElement.names.name[*].jobs ": "bosch"
}
}
Ideally, only the document containing job : bosch should be returned as a result. But for me it gives all the documents in the array name[*]. Where I am doing mistake?
Array asterisk operators are not supported by simple queries.
You need to use AQL for this:
FOR elem IN Metadata FILTER elem.rootElement.names.name[*].jobs = "bosch" RETURN elem
You can also execute AQL via the REST interface - However you should rather try to let a driver do the heavy lifting for you.