Get value from filed if another filed match condition MongoDB - mongodb

for example i have such structure of document:
{
"_id": "1230987",
"Z": [{
"A": [{
"B": {
"C": [{
"E": "2104331180",
"D": "boroda.jpg"
}, {
"E": "1450987095",
"D": "small.PNG"
}]
},
}],
}]
}
How could i get value from field E if value in field D matches condition ?

Use an $elemMatch project:
db.collection.find({"Z.A.B.C.D":<condition>},{"Z,A,B,C":{$elemMatch:{D:<condition>} }})
Playground

Related

How can I select a document where a maximum subdocument from an array has a certain property?

My document contains an array of subdocuments. Each subdocument has two values - one is a number and the other is a string. One example of such documents would be:
[{
properties:
[{
"A": "Forest",
"B": 1
},
{
"A": "Mountain",
"B": 2
},
{
"A": "Lake",
"B": 3
}]
},{
properties:
[{
"A": "Forest",
"B": 1
},
{
"A": "Lake",
"B": 2
},
{
"A": "Mountain",
"B": 3
}]
},
]
where properties is the array of subdocuments. Subdocuments are indexed by both B and A. The maximum subdocument in this context is the one with the largest B.
If I query Lake, the result is supposed to be:
[{
properties:
[{
"A": "Forest",
"B": 1
},
{
"A": "Mountain",
"B": 2
},
{
"A": "Lake",
"B": 3
}]
}]
because that is a document where the maximum subdocument contains A equal to Lake.
How can I perform this query?
I found a similar question here - Highest value from sub-arrays in documents - but this question is about retrieving the documents with the maximum B. Mine is about filtering documents by property A of maximum B.
I would appreciate any pointers.

Sum from array object value by mongodb

I am trying to solve a problem. I want to write a query that finds a document among my documents which one is greater by the sum of columns A and B's in an array. I write an example down here. I am new to MongoDB and I've been searching a lot but I could not find my solution. So can somebody help me to solve this problem? Here are my sample documents:
document1:
{
"_id" : "1",
"array": [
{
"user": "1",
"A": 2,
"B": 0
},
{
"user": "2",
"A": 3,
"B": 1},
{
"user": "3",
"A": 0,
"B": 5
}
]
}
and document 2:
{
"_id" : "2",
"array": [
{
"user": "4",
"A": 1,
"B": 1
},
{
"user": "5",
"A": 2,
"B": 2
}
]
}
for example, the sum of A and B's in all elements of an array in document 1 is 11 and the sum of A and B's in elements of an array in document 2 is 6. So I want to get document 1 for output because it is greater than 2 after summing all A and B's in all of the elements.
You can try this query:
Create an auxiliar field called total (or whatever name you want) and $add values. This add the $sum of the arrays. That means here you are adding all values from A and B together.
Then sort by the auxiliar field to get the greatest at first position
$limit to only one (the greatest)
And $project to not output the auxiliar field.
db.collection.aggregate([
{
"$addFields": {
"total": {
"$add": [
{
"$sum": "$array.A"
},
{
"$sum": "$array.B"
}
]
}
}
},
{
"$sort": {
"total": -1
}
},
{
"$limit": 1
},
{
"$project": {
"total": 0
}
}
])
Example here

MongoDB query on specific child

I've got a document that contains an array of elements. I'd like to find specific entries in that document.
Example entry 1:
{
"c": [
{
"k": "1",
"v": "1",
},
{
"k": "2",
"v": "2",
},
]
}
Example entry 2:
{
"c": [
{
"k": "1",
"v": "2",
},
{
"k": "2",
"v": "1",
},
]
}
I'd like to find all entries that have a k that is 1, and a matching v that is 1 (here, the first entry matches, but the second one doesn't, because the v that has the value of 1 is not the same object as the k valued 1).
So far, I found the query:
{
"$and": [
{"c.k": "1"},
{"c.v": "1"}
]
}
However, that returns both entries, not just the first one. Is there a way to tell MongoDB that both constraints should apply to the same item in the array, and not just to any item?
As suggested by #turiviashal, make use of the $elemMatch operator which matches documents with will match all the key conditions in at least one object.
db.collection.aggregate([
{
"$match": {
"c": {
"$elemMatch": {
"k": "1",
"v": "1",
}
}
}
}
])
Mongo Playground Example

How to add calculated fields inside subdocuments without using unwind?

I'm looking for a simple solution to add a field to a subdocument without using $unwind and $group.
I need only to calculate the sum and the size of a nested subdocuments and show it in a new field.
This is my starting collection:
{
"_id": ObjectId("5a934e000102030405000000"),
"subDoc": [
{
"a": 1,
"subArray": [1,2,3]
},
{
"b": 2
}
]
},
{
"_id": ObjectId("5a934e000102030405000001"),
"subDoc": [
{
"a": 1,
"subArray": [4,5,6]
},
{
"b": 2
},
{
"c": 3,
"subArray": [8,8,8]
}
]
}
And this is my desired result, where I've added sum (sum of subArray) and size (number of elements in subArray):
{
"_id": ObjectId("5a934e000102030405000000"),
"subDoc": [
{
"a": 1,
"subArray": [1,2,3],
"sum": 6,
"size": 3
},
{
"b": 2
"sum": 0,
"size": 0
}
]
},
{
"_id": ObjectId("5a934e000102030405000001"),
"subDoc": [
{
"a": 1,
"subArray": [4,5,6],
"sum": 15,
"size": 3
},
{
"b": 2,
"sum": 0,
"size": 0
},
{
"c": 3,
"subArray": [8,8],
"sum": 16,
"size": 2
}
]
}
I know how to obtain this result using $unwind and then $group, but I'd like to know if there is any other way (or a better way!) to achieve the same result. I've tried using $addFields and $map without success.
Working playground example: https://mongoplayground.net/p/fK8t6SLlOHa
$map to iterate loop of subDoc array
$sum to get total of subArray array of numbers
$ifNull to check if field is not present or null then return empty array because $size operator only allows array input
$size to get total elements in subArray array
$mergeObjects to merge current object with new added fields
db.collection.aggregate([
{
$addFields: {
subDoc: {
$map: {
input: "$subDoc",
in: {
$mergeObjects: [
"$$this",
{
sum: { $sum: "$$this.subArray" },
size: {
$size: { $ifNull: ["$$this.subArray", []] }
}
}
]
}
}
}
}
}
])
Playground

Get number of documents per field in MongoDB, like Studio3T Schema operation

How do I obtain the distribution of fields among a MongoDB collection, i.e the total count of documents for each field (without knowing the fields) ?
E.g. considering these documents :
{ "doc": { "a": …, "b": … } }
{ "doc": { "a": …, "c": … } }
{ "doc": { "a": …, "c": …, "d": { "e": … } } }
I would like to get
{ "a": 3, "b": 1, "c": 2, "d": 1, "d.e": 1 }
Studio3T has a "Schema" feature which does exactly that (and a bit more) for a random sample of the DB, how is the query constructed ?
One way is to use db.collection.countDocuments() with the $exists operator:
db.collection.countDocuments({ a: { $exists: true});
db.collection.countDocuments({ b: { $exists: true});
db.collection.countDocuments({ c: { $exists: true});