Removing all embedded documents - mongodb

I want to remove all embedded documents from a collection, but I can't figure out how to do that.
I have tried a few ways, but I think this one should work:
Products.update({_id: data._id}, { $pull : { orders : {$gte: 0} } });
Products is the collection, orders is the array with embedded documents.
Remove all orders where the index is greater or equal than 0.
No luck.

Try this
db.products.update({_id: data._id},
{$unset: {orders: 1}})
or this
db.products.update({_id: data._id},
{$set: {orders: []}})

Related

How to delete duplicates using MongoDB Aggregations in MongoDB Compass Community

I somehow created duplicates of every single entry in my database. Currently, there are 176039 documents and counting, half are duplicates. Each document is structured like so
_id : 5b41d9ccf10fcf0014fe8917
originName : "Hartsfield Jackson Atlanta International Airport"
destinationName : "Antigua"
totalDuration : 337
Inside the MongoDB Compass Community App for Mac under the Aggregations tab, I was able to find duplicates using this pipeline
[
{$group: {
_id: {originName: "$originName", destinationName: "$destinationName"},
count: {$sum: 1}}},
{$match: {count: {"$gt": 1}}}
]
I'm not sure how to move forward and delete the duplicates at this point. I'm assuming it has something to do with $out.
Edit: Something I didn't notice until now is that the values for totalDuration on each double are actually different.
Add
{$project:{_id:0, "originName":"$_id.originName", "destinationName":"$_id.destinationName"}},
{ $out : collectionname }
This will replace the documents in your current collection with documents from aggregation pipeline. If you need totalDuration in the collection then add that field in both group and project stage before running the pipeline

removing element of an array that with a match of certain element

I have a mongodb collection.
{ user_id: 1,
items : [ { _id: 1 }, { _id: 2}, {_id:3} ] }
I want to remove the items of the array having specific id. Can anybody explain what is wrong with the above query.
db.col.findOneAndUpdate({user_id:1},{$pull:{items:{$elemMatch:{_id:2}}}})
$pull takes an expression as a parameter so you don't have to use $elemMatch (doesn't work in this case). Try:
db.col.update({user_id:1},{$pull:{items:{_id:2}}})
So expression in this case means that MongoDB will remove the document having _id set to 2 but that document can have other properties as well.

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 }}
])

Meteor + Mongo (2.6.7) Pushing Document to Array in Sorted Order

I have a document with an array (which should be denormalised, but can't be because the reactive events will fire "add" too many times at client startup).
I need to be able to push a document to that array, and keep it in sorted (or roughly sorted) order. I've tried this query:
{ $push: {
'events': {
$each: [{'id': new Mongo.ObjectID, 'start':startDate,...}],
$sort: {'start': 1},
$slice: -1
}
}
But it requires the $slice operator to be present... I don't want to delete all my old data, I just want to be able to insert data into an array, and then have that array be sorted so that I can query the array later and say "slice greater than or equal to time X".
Is this possible?
Edit:
This mongo aggregate query nearly works, except for one level of document in the result array, but aggregating is not reactive (probably because they're expensive computations). Here is the aggregate query if anyone can see how to translate it to a find, or why it can't be translated:
Coll.aggregate({$unwind: '$events'},
{$sort: {'events.start':1}},
{$match: {'events.start': {$gte: new Date()}}},
{$group: {_id: '$_id', 'events': {$push: '$events'} }})

MongoDB - Clearing items in a nested array

If I have a nested array in my schema, how do I tell MongoDB to remove its entries for a specific model?
Schema
var UserSchema = new Schema({
username: String,
documents: [Number]
});
I tried something like this:
db.users.update({"username": "tom"}, {"$pullAll": {"documents": []}})
But the items in the nested array are still there.
Your code is not working, because $pullAll requires list of items which should be removed from array. You are passing empty array, thus nothing is removed.
You can simply set documents to empty array instead of removing all items:
db.users.update({"username": "tom"}, {"$set": {"documents": []}})
If you want to avoid creating documents array if "tom" do not have it, then check if array exists when selecting document to update:
db.users.update({username: "tom", documents: {$exists: true}},
{$set: {documents: []}})
UPDATE: Another option to remove all array items is to use $pull with query which satisfies all documents:
db.users.update({username: "tom"}, {$pull: {documents: {$exists: true}}})