In below document i have to update the "value": "7" object.How can i do that.if one array means we can use $.if we know index of the array also we can do that but in my case i cant apply more than one $ and also i don't have index info.
{
"data": [
{
"value": "1",
"children": [
{
"value": "2",
"children": [
{
"value": "3",
"children": [
{
"value": "4",
"children": [
{
"value": "aaa"
}
]
}
]
}
]
},
{
"value": "5",
"children": [
{
"value": "6",
"children": [
{
"value": "7",
"children": [ // i want to update this value
{
"value": "bbb"
}
]
}
]
}
]
}
]
}
]
}
Related
Playground:https://mongoplayground.net/p/YUV_fReyGsr
I have following query. I need to combine the result 2 by 2. Meaning I need to combine facet "1","2" as a result and facet "3","4" as another result. It's guaranteed that the number of facet will be even. Also, each pair of facet should get at most one record(it might not matter)
db.collection.aggregate([
{
"$facet": {
"1": [
{
$match: {
"ID": "2"
}
}
],
"2": [
{
$match: {
"array.ID": "2"
}
}
],
"3": [
{
$match: {
"array.ID": "4"
}
}
],
"4": [
{
$match: {
"ID": "4"
}
}
]
}
}
])
The expected result will be
[
{
"1": [
{
"ID": "1",
"array": [
{
"ID": "2",
"attribute1": "456"
},
{
"ID": "3",
"attribute1": "567"
}
],
"attr1": "123"
}
],
"2": [
{
"ID": "4",
"array": [
{
"ID": "5",
"attr1": "456"
}
],
"attr1": "123"
}
]
}
]
I was able to figure this out using $concatArrays operator, along with $project.
Live demo here
Database
[
{
"ID": "1",
"attr1": "123",
"array": [
{
"ID": "2",
"attribute1": "456"
},
{
"ID": "3",
"attribute1": "567"
}
]
},
{
"ID": "4",
"attr1": "123",
"array": [
{
"ID": "5",
"attr1": "456"
}
]
}
]
Query
db.collection.aggregate([
{
"$facet": {
"1": [
{
$match: {
"ID": "2"
}
}
],
"2": [
{
$match: {
"array.ID": "2"
}
}
],
"3": [
{
$match: {
"array.ID": "4"
}
}
],
"4": [
{
$match: {
"ID": "4"
}
}
]
}
},
{
"$project": {
_id: 0,
"1": {
"$concatArrays": [
"$1",
"$2"
]
},
"2": {
"$concatArrays": [
"$3",
"$4"
]
}
}
}
])
Result
[
{
"1": [
{
"ID": "1",
"_id": ObjectId("5a934e000102030405000000"),
"array": [
{
"ID": "2",
"attribute1": "456"
},
{
"ID": "3",
"attribute1": "567"
}
],
"attr1": "123"
}
],
"2": [
{
"ID": "4",
"_id": ObjectId("5a934e000102030405000001"),
"array": [
{
"ID": "5",
"attr1": "456"
}
],
"attr1": "123"
}
]
}
]
I try to filter some results data from mongodb with mongoose in javascript.
This is my json structure:
{
"name": "john",
"firstname": "doe",
"yearold": 22,
"recipes": [
{
"title": "cheesecake",
"data": [
{
"name": "egg",
"label": "Eggs for",
"value": 6,
"unit": "piece"
},
{
"name": "oil",
"label": "Specific oil",
"unit": "oz",
"value": 0.2
},
{
"name": "flour",
"label": "Wholemel flour",
"value": 450,
"unit": "gr"
}
]
},
{
"title": "cake",
"data": [
{
"name": "egg",
"label": "Eggs for",
"value": 6,
"unit": "piece"
},
{
"name": "flour",
"label": "Wholemel flour",
"value": 500,
"unit": "gr"
},
]
}
]
}
In some case i need to return json data with hiding some values. For example I have a list that specifies all the values to hide
hidekeys=["egg"];
and i would like to get this:
{
"name": "john",
"firstname": "doe",
"yearold": 22,
"recipes": [
{
"title": "cheesecake",
"data": [
{
"name": "egg",
"label": "Eggs for",
"value": #######,
"unit": "piece"
},
{
"name": "oil",
"label": "Specific oil",
"unit": "oz",
"value": 0.2
},
{
"name": "flour",
"label": "Wholemel flour",
"value": 450,
"unit": "gr"
}
]
},
{
"title": "cake",
"data": [
{
"name": "egg",
"label": "Eggs for",
"value": #######,
"unit": "piece"
},
{
"name": "flour",
"label": "Wholemel flour",
"value": 500,
"unit": "gr"
},
]
}
]
}
For each recipe i need to hide ingredient value if it is specified in hidekeys.
I tried something with $project and $cond but it doesnt works
Here's a quick way of how to achieve this using $map
const hidekeys = ["egg"];
db.collection.aggregate([
{
$addFields: {
recipes: {
$map: {
input: "$recipes",
as: "recipe",
in: {
$mergeObjects: [
"$$recipe",
{
data: {
$map: {
input: "$$recipe.data",
as: "datum",
in: {
"$mergeObjects": [
"$$datum",
{
$cond: [
{
"$setIsSubset": [
[
"$$datum.name"
],
hidekeys
]
},
{
value: "#####"
},
{
value: "$$datum.value"
}
]
}
]
}
}
}
}
]
}
}
}
}
}
])
Mongo Playground
Im using mongoose, I have the following data of user collection:
[{
"_id": "1",
"notes": [
{
"value": "A90",
"text": "math"
},
{
"value": "A80",
"text": "english"
},
{
"value": "A70",
"text": "art"
}
]
},
{
"_id": "2",
"notes": [
{
"value": "A90",
"text": "math"
},
{
"value": "A80",
"text": "english"
}
]
},
{
"_id": "3",
"notes": [
{
"value": "A80",
"text": "art"
}
]
}]
and I have as a parameters the following array: [ "A90", "A80" ]
so I want to make a query to use this array to return only the records that have all the array items in the notes (value) table.
So for the example above it will return:
[{
"_id": "1",
"notes": [
{
"value": "A90",
"text": "math"
},
{
"value": "A80",
"text": "english"
},
{
"value": "A70",
"text": "art"
}
]
},
{
"_id": "2",
"notes": [
{
"value": "A90",
"text": "math"
},
{
"value": "A80",
"text": "english"
}
]
}]
I tried the following find query:
{ "notes": { $elemMatch: { value: { $in: valuesArray } } }}
but it returns a record even if just one element in valuesArray exist.
it turned out to be quite easy:
find({ "notes.value": { $all: arrayValues } })
here are 2 possibilities for a note taking database that will have multiple notes for multiple users to keep track of
1.
[
{
"_id": "abcd",
"userInfo": {
"userID": "1",
"notes": [
{
"noteID": "1",
"text": "123"
},
{
"noteID": "2",
"text": "456"
},
{
"noteID": "3",
"text": "789"
}
]
}
},
{
"_id": "efgh",
"userInfo": {
"userID": "2",
"notes": [
{
"noteID": "1",
"text": "123"
},
{
"noteID": "2",
"text": "456"
}
]
}
}
]
And the 2nd option:
[
{
"_id": "abcd",
"userID": "1",
"noteID": "1",
"text": "123"
},
{
"_id": "efgh",
"userID": "1",
"noteID": "2",
"text": "456"
},
{
"_id": "ijkl",
"userID": "1",
"noteID": "3",
"text": "789"
},
{
"_id": "mnop",
"userID": "2",
"noteID": "1",
"text": "123"
},
{
"_id": "wxyz",
"userID": "2",
"noteID": "2",
"text": "123"
}
]
I'd expect 1 to have a much better performance when it comes to loading notes for a single user(if the user has a ton of notes). However, 2nd option is much better when modifying and adding individual notes.
I have a collection with this structure:
{
"name": "1",
"array1": [
{
"arrayname1A" : "A",
"array2": [
{ "value": "1" },
{ "value": "3" }
]
},
{
"arrayname1B": "B",
"array2": [
{ "value": "5" },
]
}
]
},
{
"name": "2",
"array1": [
{
"arrayname1A": "A",
"array2": [
{ "value": "1" },
{ "value": "7" }
]
}
]
}
How can I extract the unique "value" from every different array2? The end result I am looking for would be something like "1","3","5","7" with no repeated values.
Simply use the distinct() method and the dot notation to access the "value" field.
db.collection.distinct('array1.array2.value')
which yields:
[ "1", "3", "5", "7" ]