DeleteMany in mongoDb only deleting first condition data - mongodb

I am trying to delete multiple rows in mongo db by multiple conditions but i see only first condition data is deleted. Please Someone help. Sharing the data for clarification.
Data:
{
"_id": ObjectId("601fcc2f4bae4bc542085e8b"),
"name": "tutoria 2",
"id": 19,
"rollno": 1020,
"amount": "one hundred only"
}{
"_id": ObjectId("601fce9a4bae4bc542085e8e"),
"name": "tutoria 2",
"id": 19,
"rollno": 1020,
"amount": "hundred only"
}{
"_id": ObjectId("601fcea44bae4bc542085e8f"),
"name": "tutoria 3",
"id": 10,
"rollno": 1020,
"amount": "hundred only"
}{
"_id": ObjectId("601fceb04bae4bc542085e90"),
"name": "tutoria 4",
"id": 21,
"rollno": 1020,
"amount": "hundred only"
}
Query:
db.movie.deleteMany(
{
"name": "tutoria 4"
},
{
"id": 10
}
)
{
"acknowledged": true,
"deletedCount": 1
}
Not sure what's wrong with mongoose.

It worked by this.
db.movie.deleteMany({$or:[{"name":"tutoria 098"},{"id":20}]})

Try this one:
db.collection.deleteMany({
$and: [
{name:"tutoria 4"},
{id:10}
]
})
All matching query $and should return true to delete filtered documents, otherwise it won't delete at all.

Related

Need to aggregate and return results based on document nested array

I have the following document:
{
"_id": ObjectId("10..."),
"ownerName": "Merchant 10",
...,
"stores": [
{
"id": ObjectId("20..."),
"storeName": "Store 20"
},
{
"id": ObjectId("21..."),
"storeName": "Store 21"
}
]
},
{
"_id": ObjectId("11..."),
"ownerName": "Merchant 11",
...,
"stores": [
{
"id": ObjectId("22..."),
"storeName": "Store 22"
}
]
}
Is it possible with aggregate to return paginated results based on nested array "stores", and end up with the following result:
{
"_id": "20...",
"ownerName": "Merchant 10",
"storeName": "Store 20"
}, {
"_id": "21...",
"ownerName": "Merchant 10",
"storeName": "Store 21"
}, {
"_id": "22...",
"ownerName": "Merchant 11",
"storeName": "Store 22"
},
So basically, I would like to be able to share owner info but returning result based on stores.
I tried another way with a stores document but with my specific requirement, I ended up with a circular dependency.
Thanks
Using unwind on stores you can flatten out the documents. After that, just project the fields you need:
db.mycollection.aggregate( [
{ $unwind: "$stores" },
{ $project: { "ownerName": 1, "storeName": "$stores.storeName" } }
] )

How to update specific field in mongoDB given conditions?

Given the following mongdoDB structure, how can i update the field isAvailable to false given that the shopName is "jamrt" and slug is "67626dae-1537-40d8-837d-483e5759ada0". This is my query but it does not work: Shop.find({ shopName: shopName}).update({products: {$elemMatch: {slug: slug}}}, { $set: { isAvailable: req.body.isAvailable} } Thanks!
"shopName": "jmart",
"products": [{
"id": 1,
"name": "Clean and Clear Deep Clean Cleanser 100g",
"slug": "8d1c895c-6911-4fc8-a34c-89c6948233d7",
"price": 4.5,
"discount_price": 0,
"category": "Health and Beauty",
"sale": false,
"subcategory": "personal care",
"color": "black",
"article": "Clean and Clear",
"quantity": 9,
"img": "https://firebasestorage.googleapis.com/v0/b/swifty-products.appspot.com/o/Jmart%2FBeauty%2FClean%20and%20Clear%20Deep%20Clean%20Cleanser%20100g.jpg?alt=media",
"vendor": {
"id": 1,
"name": "Clean and Clear"
},
"ratings": {
"star_ratings": 0,
"votes": 0
},
"isAvailable": true
}, {
"id": 2,
"name": "Colgate Total Pro Breath Health",
"slug": "67626dae-1537-40d8-837d-483e5759ada0",
"price": 4.5,
"discount_price": 0,
"category": "Health and Beauty",
"sale": false,
"subcategory": "personal care",
"color": "black",
"article": "Colgate",
"quantity": 9,
"img": "https://firebasestorage.googleapis.com/v0/b/swifty-products.appspot.com/o/Jmart%2FBeauty%2FColgate%20Total%20Pro%20Breath%20Health.jpg?alt=media",
"vendor": {
"id": 2,
"name": "Colgate"
},
"ratings": {
"star_ratings": 0,
"votes": 0
},
"isAvailable": true
},
]
In your case, you are trying to update only the matching sub documents.
The $elemMatch operator while using in projection updates only the first matching sub document.
The $elemMatch operator while using in find updates all the fields of the matching document.
This solution might help you.
With your case, the solution might be the below in mongodb query:
db.Shop.update({"shopName":"jmart","products.slug":"67626dae-1537-40d8-837d-483e5759ada0"}, {$set: {“products.$[i].isAvailable”: false}}, {arrayFilters: [{“i.slug”: "67626dae-1537-40d8-837d-483e5759ada0"}]})

Update single sub document in multiple array in mgo

I have following mongodb (3.4.x) document, i code in golang with mgo driver
{
"id": "5981d4c2795a1b4a801ee027",
"scenarioId": "59804b10d8ee910085e33865",
"messages": [
{
"id": "5981d4c2795a1b4a801ee028",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee029",
"to": {
"email": "some#email.com"
},
"channel": "EMAIL",
"toType": "EMAIL",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02a",
"to": {
"phone": "+381631891245"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
},
{
"id": "5981d4c2795a1b4a801ee02b",
"toQueue": [
{
"id": "5981d4c2795a1b4a801ee02c",
"to": {
"phone": "+123456789"
},
"channel": "SMS",
"toType": "PHONE",
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
],
"messageStages": [
{
"id": "5981d4c2795a1b4a801ee033",
"validityPeriod": 5,
"validityPeriodTimeUnit": "MINUTES",
"providerId": 5,
"email": {
"text": "this is the email text",
"subject": "and here the email subject"
},
"status": {
"id": 1,
"groupId": 1,
"groupName": "PROCESSING",
"name": "APPROVED",
"description": "MessageChain approved for processing"
}
}
]
}
and I know the value of messages.$.toQueue.id, where i want to update status.id in the related toQueue Array Item.
I tried to do it that way:
query = bson.M{
"messages.toQueue._id": toQueueId,
}
update = bson.M{
"$set": bson.M{
"messages.$.toQueue.$.status.id": status.Id,
"messages.$.toQueue.$.status.name": status.Name,
"messages.$.toQueue.$.status.groupId": status.GroupId,
"messages.$.toQueue.$.status.groupName": status.GroupName,
"messages.$.toQueue.$.status.description": status.Description,
},
}
err = cr.Update(query,update)
but multiple $ are not allowed. Without it's also not updateable.
Is there any way to update only the subdocument, which i found in query ?
Neil Lunn gave the right answer.
It's not possible to work with nested arrays the way I tried to do. And he is also right, that problem is coming from design mistake.
So I changed it as him and Markus W Mahlberg suggested to move the toQueue part in a separate collection, with messageId as a reference.

MongoDB: Return deeply nested document from it's id regardless of level

I have a collection consisting of documents that are made up of an id, name and an array of items; the array in each document is supposed to nest other documents of the same structure when applicable, and there is no limit to how many nested arrays of documents there are (nested documents can also have nested documents).
Using the MongoClient package, I'm trying to query my collection and return a document based on it's id, regardless of it's location in the data (be it at the top level or 3 levels down).
So far I can return any top level data okay, but my query is not finding any nested data. I've seen similar questions where the data structure is limited and consistent, but as my data is dynamic and multi-layered, I haven't find a solution that fits this particular issue.
Here's my data:
[
{
"_id": 1,
"name": "Test 1",
"items": []
},
{
"_id": 2,
"name": "Test 2",
"items": [
{
"_id": 3,
"name": "Test 3",
"items": []
},
{
"_id": 4,
"name": "Test 4",
"items": [
{
"_id": 6,
"name": "Test 6",
"items": []
}
]
}
]
},
{
"_id": 5,
"name": "Test 5",
"items": []
}
]
Here's my Mongo query:
MongoClient.connect(connString, function(err, db) {
var collection = db.collection('items');
collection.findOne({_id: ObjectID("4")}, function(err, result) {
console.log(result);
});
db.close();
});
And result is intended to return the following, but returns null instead:
{
"_id": 4,
"name": "Test 4",
"items": [
{
"_id": 6,
"name": "Test 6",
"items": []
}
]
}
Can anyone share a solution as to how I can retrieve my data as intended?
It is not possible to query an infinate amount of document of documents due to the change of properties at each level. See Query Selectors (https://docs.mongodb.com/manual/reference/operator/query/#query-selectors) for a list of selectors that can be used.
However if it's possbile to limit or give a depth limit on the items then you could use a query such as:-
db.col.find( {$or: [ { "_id" : id }, { "items._id" : id }, { "items.items._id" : id }, { "items.items.items._id" : id } ] } );
If it's not possible to give a depth limit I'd advise re-modeling the document in to something like:
[
{
"_id": 1,
"name": "Test 1"
},
{
"_id": 3,
"name": "Test 3",
"parentId": 2
},
{
"_id": 6,
"name": "Test 6",
"parentId": 4
},
{
"_id": 4,
"name": "Test 4",
"parentId": 2
},
{
"_id": 2,
"name": "Test 2",
},
{
"_id": 5,
"name": "Test 5",
}
]
Then you could do a simple find by _id query:
> db.collection.find({_id: 4})
{ "_id" : 4, "name" : "Test 4", "parentId" : 2 }
If you also need to retain the document structure of the query you can use the $graphLookup aggregation stage.

Elasticsearch nested query

I'm new to elasticsearch, managed to set it up and import recordset from my mongodb collection using the river plugin. For a start, I want to query against the "desc" field but just can't manage to get the query .. not sure if the problem is driven by the way index was defined.. can anyone help please?
Sample recordset in elastic search looks like this
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 107209,
"max_score": 1,
"hits": [
{
"_index": "shiv",
"_type": "shiv",
"_id": "iG1eIzN7RGO7hFfxTlnLuA",
"_score": 1,
"_source": {
"_id": {
"$oid": "50901d7f485bf7bd1c000021"
},
"brand": "",
"category": {
"$ref": "categories",
"$id": {
"$oid": "4fbd2221758cb11d14000174"
}
},
"comments": [],
"count_comment": 0,
"count_fav": 2,
"count_hotness": 1.46,
"count_rekick": 0,
"count_share": 0,
"country": {
"$ref": "countries",
"$id": {
"$oid": "4fec98f7758cb18c6e0002c9"
}
},
"currency": "pound",
"desc": "A men's automatic watch, this Seamaster Bond model features a Co-Axial escapement and date function. Its blue dial is teamed with a stainless steel case and bracelet for a look that's sporty and refined.",
"gender": "male",
"ident": "omega-seamaster-diver-bond-men-s-automatic-watch---ernest-jones-1351622015",
"img_url": "http://s7ondemand4.scene7.com/is/image/Signet/5735793?$detail$",
"lifestyles": [
{
"$ref": "lifestyles",
"$id": {
"$oid": "508ff6ca485bf73112000060"
}
}
],
"location": "United Kingdom",
"owner": {
"$ref": "accounts",
"$id": {
"$oid": "50742fd8485bf74b7a00213f"
}
},
"price": 2400,
"store": "ernestjones.co.uk",
"tags": [
"ernest-jones",
"bond"
],
"timestamp_creation": 1351622015,
"timestamp_exp": 1356825600,
"timestamp_update": 1351622015,
"title": "Omega Seamaster Diver Bond men's automatic watch - Ernest Jones",
"url": "http%3A%2F%2Fwww.ernestjones.co.uk%2Fwebstore%2Fd%2F5735793%2Fomega%20seamaster%20diver%20bond%20men%27s%20automatic%20watch%2F%3Futm_source%3Dgooglebase%26utm_medium%3Dfeedmanager%26cm_mmc%3DFroogle-_-CKB-_-nurses_fobs-_-watches%26cm_mmca1%3Domega%26cm_mmca2%3Dmale%26cm_mmca3%3Dadult"
}
}
]
}
}
The mapping of the index "shiv" looks like
{
"shiv": {
"properties": {
"$oid": {
"type": "string"
}
}
}
}
Thanks again
There are lots of ways to query, have you tried a match query?
Using curl or a rest client of your choice...
http://[host]:9200/[index_name]/[doc_type]/_search
{
"query" : {
"match" : {
"desc" : "some value you want to find in desc"
}
}
}