MongoDB: Count documents in array of nested document for a specific field in the main document - mongodb

i have this collection on MongoDB
Collection structure
The main document has like main Field wineName. Now in this image the array of nested document (reviews) is only one but could be several reviews for each wines.
My question is how can I count the number of reviews that I have for each Wine?
Thank you in advance for the answer

You can use the $size aggregation operator for this:
db.collection.aggregate([
{
"$addFields": {
"reviewCount": {
$size: "$reviews"
}
}
}
])
Mongo Playground

Related

Query to delete the last three documents in a collection in mongodb

Consider my database collection is having 5 documents and I need to delete the last 3 documents. So what is the query in Mongodb
Maybe something like this:
db.collection.aggregate([
{
$sort: {
_id: 1
}
},
{
$limit: 2
},
{
$out: "collection"
}
])
Explained:
Sort collection by inserted order
FIlter only the first 2 documents.
Store back the content to the original collection replacing the original.
Playground

How to write group by query for embedded array of document in mongodb

I have a collection in below format
{customerID:1,acctDetails:[{accType:"Saving",balance:100},{accType:"checking",balance:500}]}
{customerID:2,acctDetails:[{accType:"Saving",balance:500}]}
I want to find total balance by acctType. I tried below query.
db.<collectionName>.aggregate([{$group:{_id:"$acctDetails.accType",totalBalance:{$sum:"$accDetails.balace"}}}])
But it is not giving right result.
I think that this might solve your problem. You first need to use $unwind to transform each array element in a document, then use $group to sum the total balance by account type.
db.collection.aggregate([
{"$unwind": "$acctDetails"},
{
"$group": {
"_id": "$acctDetails.accType",
"totalBalance": {"$sum": "$acctDetails.balance"}
}
}
])
Working Mongo playground

MongoDB querying aggregation in one single document

I have a short but important question. I am new to MongoDB and querying.
My database looks like the following: I only have one document stored in my database (sorry for blurring).
The document consists of different fields:
two are blurred and not important
datum -> date
instance -> Array with an Embedded Document Object; Our instance has an id, two not important fields and a code.
Now I want to query how many times an object in my instance array has the group "a" and a text "sample"?
Is this even possible?
I only found methods to count how many documents have something...
I am using Mongo Compass, but i can also use Pymongo, Mongoengine or every other different tool for querying the mongodb.
Thank you in advance and if you have more questions please leave a comment!
You can try this
db.collection.aggregate([
{
$unwind: "$instance"
},
{
$unwind: "$instance.label"
},
{
$match: {
"instance.label.group": "a",
"instance.label.text": "sample",
}
},
{
$group: {
_id: {
group: "$instance.label.group",
text: "$instance.label.text"
},
count: {
$sum: 1
}
}
}
])

Combine two similar documents MongoDB

Is there any possible way to combine two documents in mongodb?
Imagine I have a collection with this documents:
{ "_id":ObjectId("142342432"), "name":"Chris", "surname":"Patrick", "pets":["dog", "cat"] }
{ "_id":ObjectId("142342752"), "name":"Chris", "surname":"Patrick", "pets":["lizard"] }
more than x2000 documents
And some other documentes. My idea would be to group each of the entries by name and surname and in case they match, join the pets array $addToSet.
The idea is to delete those two documents and add a new one with a new generated id and the combination. Deleting one document and appending the array to the other one, would also be ok.
My main problem is that I should be updating the collection, so it wouldn't be just a dump. And it can't be inefficient to dump it into a file and import it later on.
Thanks!
Update: Using mongodb 3.4
you can achieve this in a single query :
first, unwind pets array
then, group by name and surname, and combine arrays with $addToSet
finally, write the output to the same collection using $out
Be carefull, this will overwrite the original collection!
before running this, you should create a dump of your current collection to avoid any data loss
here is the query:
db.collectionName.aggregate([
{ $unwind: {
path: "$pets",
preserveNullAndEmptyArrays: true
}
},
{
$group:{
_id:{
name:"$name",
surname:"$surname"
},
pets:{
$addToSet:"$pets"
},
otherField: {
$first: "$otherField"
}
}
},
{
$out:"collectionName"
}
])

mongo find function mismatch

Mongo version : 3.2.8
My sample json is as below
My query to fetch name equal to apple doesn't work.
db.collection.find( { "products.foods.name": "apple" } )
Instead it fetches all the records, strange?
Neither does the $eq, $lt or $gt work. They result with the entire data.
db.aggregation.find( { "products.foods.min_price": {$eq:10} } )
Thanks in advance.
If your entire document is in an _id, then if the query matches db.collection.find( { "products.foods.name": "apple" } ) even though it is a document in foods array the entire document will be displayed, so that you are getting other fruits as well.
To Solve this first use $unwind the aggregation pipeline to break the foods array into individual documents and then use $match.
Please refer this post, It is a similar question and I have answered the steps in detail in that post.
Try with this:
db.test.aggregate([
{$match: {'products.foods.name': 'apple'}}])
Taken from Retrieve only the queried element in an object array in MongoDB collection
You can try other examples from that post.
Try with this:db.Exercise.aggregate([
{$match: {'products.foods.min_price': 10}}])
The solution is to n $unwind both the arrays.
db.foods.aggregate([
{ $unwind : "$products" },
{ $unwind : "$products.foods" },
{ $match : { "products.foods.min_price": 10 }}
])