mongo remove item in document from array - mongodb

i have the following document in my collection:
"_id" : "12345",
"name" : "test",
"users" : [
{
"name" : "spiderman",
"email" : "spiderman#spiderman.com",
"accepted" : true
},
{
"name" : "superman",
"email" : "superman#superman.com",
"accepted" : true
}
]
I would like to remove the user superman.
This is what i would like my final result to look like:
"_id" : "12345",
"name" : "test",
"users" : [
{
"name" : "spiderman",
"email" : "spiderman#spiderman.com",
"accepted" : true
}
]
Ive tried a few things but nothing worked so far. Any help is appreciated.
Thank you

You can use $pull
db.collection.update(
{ "users.name": "superman" },
{ $pull: { "users": {"name" : "superman"} } },
{ multi: false}
)

Related

Update query on in the collection by "_id"

{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "abc",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00.000Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
I need to update the "templateName" : "xyz" on the basis of "_id" : "tenant/data/EMAIL/ENGLISH"
I have tried these queries but got no success
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.$.templateName" : "XYZ"}}); 
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.templateName" : "XYZ"}}); 
Any help will be appreciated.
I have used positional-all operator to update the array.
Here is the query:
db.sample.update(
{
"_id": "tenant/data/EMAIL/ENGLISH"
},
{
$set:{
"template.$[].templateName":"XYZ"
}
}
)
Output
{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "XYZ",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
hope this will help :)

MongoDb: Straightforward query doesn't work

I don't quite figure out why I'm getting different results when:
> db.reference.find({"metadata.values": {address: {location: "barcelona"} } }).count();
0
> db.reference.find({"metadata.values.address.location": "barcelona"}).count();
1
Which is the difference?
The document contained into reference collection is:
{
"_id" : "Doc1Ref2",
"document" : "doc1",
"metadata" : [
{
"_id" : "Doc1Ref2Mdt1",
"user" : "user2",
"creationTimestamp" : ISODate("2018-09-24T12:20:56.169Z"),
"values" : {
"date" : ISODate("2018-09-24T12:20:56.171Z"),
"number" : 16,
"address" : {
"street" : "Av. Diagonal",
"location" : "barcelona"
},
"credentials" : [
{
"password" : "pwd",
"login" : "main"
},
{
"password" : "pwd",
"login" : "other",
"creation" : ISODate("2018-09-24T12:20:56.171Z")
}
],
"contact" : "contact name",
"tags" : [
"tag1",
"tag2"
]
}
}
],
"timestampCreation" : ISODate("2018-09-24T12:20:56.169Z")
}
The first query matches documents where metadata.values is an exact object {address: {location: "barcelona"} }, the second is where metadata.values has an object with address.location equal to "barcelona".
The equivalent tests in javascript:
if ((document.metadata || {}).values == {address: {location: "barcelona"} })
and
if ((((document.metadata || {}).values || {}).address || {}).location == "barcelona")

MongoDB query with multiple conditions

I have data with multiple documents :
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e486"),
"empId" : "1"
"type" : "WebUser",
"city" : "Pune"
}
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e487"),
"empId" : "2"
"type" : "Admin",
"city" : "Mumbai"
}
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e488"),
"empId" : "3"
"type" : "Admin",
"city" : "Pune"
}
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e489"),
"empId" : "4"
"type" : "User",
"city" : "Mumbai"
}
I want to get data according to my multiple conditions :
condition 1:- {"type" : "WebUser", "city" : "Pune"}
condition 2:- {"type" : "WebUser", "city" : "Pune"} & {"type" : "User", "city" : "Mumbai"}
I want below result when run condition 1 :
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e486"),
"empId" : "1"
"type" : "WebUser",
"city" : "Pune"
}
When I run second condition :
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e486"),
"empId" : "1"
"type" : "WebUser",
"city" : "Pune"
}
{
"_id" : ObjectId("57b68dbbc19c0bd86d62e489"),
"empId" : "4"
"type" : "User",
"city" : "Mumbai"
}
I want above result by one query,
Currently I am using below aggregate query,
db.emp.aggregate([
{ $match: { '$and': [
{"type" : "WebUser", "city" : "Pune"},
{"type" : "User", "city" : "Mumbai"}
] } },
{ $group: { _id: 1, ids: { $push: "$empId" } } }
])
Above query work for first condition & fails for other. Please help me.
For the second condition, you can use the $in operator in your query as:
db.emp.find({
"type" : { "$in": ["WebUser", "User"] },
"city" : { "$in": ["Pune", "Mumbai"] }
})
If you want to use in aggregation:
db.emp.aggregate([
{
"$match": {
"type" : { "$in": ["WebUser", "User"] },
"city" : { "$in": ["Pune", "Mumbai"] }
}
},
{ "$group": { "_id": null, "ids": { "$push": "$empId" } } }
])
or simply use the distinct() method to return an array of distinct empIds that match the above query as:
var employeeIds = db.emp.distinct("empId", {
"type" : { "$in": ["WebUser", "User"] },
"city" : { "$in": ["Pune", "Mumbai"] }
});
If you are looking for the AND operator
This example checks if a field exists AND is null
db.getCollection('TheCollection').find({
$and: [
{'the_key': { $exists: true }},
{'the_key': null}
]
})
This example checks if a field has 'value1' OR 'value2'
db.getCollection('TheCollection').find({
$or: [
{'the_key': 'value1'},
{`the_key': 'value2'}
]
})
When just checking for null, the return contains non-existing fields plus fields with value null
db.getCollection('TheCollection').find({'the_key': null})
You can use mongo db $or operator.
db.emp.find({ $or: [
{ "type": "WebUser", "city": "Pune" },
{ "type": "user", "city": "Mumbai"}
]})
You can pass conditions in the array.
For more reference see mongo docs
Display the document where in the “StudName” has value “Ajay Rathod”.
db.Student.find({name:"ajay rathod"})
{ "_id" : ObjectId("5fdd895cd2d5a20ee8cea0de"), "
Retrieve only Student Name and Grade.
db.Student.find({},{name:1,grade:1,_id:0})
{ "name" : "dhruv", "grade" : "A" }
{ "name" : "jay", "grade" : "B" }
{ "name" : "abhi", "grade" : "C" }
{ "name" : "aayush", "grade" : "A" }
{ "name" : "sukhdev", "grade" : "B" }
{ "name" : "dhruval", "grade" : "B" }
{ "name" : "ajay rathod", "grade" : "D" }

Retrieving group by result with arrays in mongo

I have mongo documents in the following format. I want to get the devices_ids for each unique phone_numbers but my mongo query is not giving proper result.
Can anyone point out my problem ?
{
"_id" : ObjectId("56cf21562e7b232d022f334e871"),
"uid" : 5,
"device_id" : "352136234234325",
"name" : "user1",
"email" : ["user1#mail.com" ],
"phone_number" : [
"+919890273451"
]
}
{
"_id" : ObjectId("56cf21562e7b2d032422f334e872"),
"uid" : 15,
"device_id" : "3521360123444",
"name" : "user1",
"email" : [ "user1#mail.com"],
"phone_number" : [
"+919890273451"
]
}
{
"_id" : ObjectId("56cf21562342e7b2d022f334e873"),
"uid" : 51,
"device_id" : "352136067208559",
"name" : "user1",
"email" : [ "user1#mail.com"],
"phone_number" : [
"+919890273451"
]
}
My expected output is
{
"phone_number" : "+919890273451",
device_ids : ["352136067208559","3521360123444","352136234234325"]}
}
I have tried this query:
db.contact.aggregate([{
$unwind: "$phone_number"
},
{$group: {"_id":"$phone_number"},
device_ids: { $push: { user: "$device_id"} }
}
], {
allowDiskUse:true,
cursor:{}
});
when using $push you don't need to specify touple name - just push plain value.
Please see below:
db.coll.aggregate([{
$unwind : "$phone_number"
}, {
$group : {
_id : "$phone_number",
device_ids : {
$addToSet : "$device_id"
}
}
}
])

MongoDB find documents if a property array doesn't contain an object

I have a list of documents like this.
[
{
"name" : "test",
"data" : [
{ "code" : "name", "value" : "Diego" },
{ "code" : "nick", "value" : "Darko" },
{ "code" : "special", "value" : true }
]
},
{
"name" : "another",
"data" : [
{ "code" : "name", "value" : "Antonio" },
{ "code" : "nick", "value" : "Tony" }
]
}
]
now I need to find all the documents that:
a) don't contain a "data" item with code "special"
OR
b) contains a "data" item with code "special" and value false
It's like I needed the opposite of $elemMatch or I'm missing something?
I'm assuming that you're inserting each document in your list of documents as a separate member of a collection test.
For a,
db.test.find({ "data.code" : { "$ne" : "special" } })
For b.,
db.test.find({ "data" : { "$elemMatch" : { "code" : "special", "value" : false } } })
Combining the two with $or,
db.test.find({ "$or" : [
{ "data.code" : { "$ne" : "special" } },
{ "data" : { "$elemMatch" : { "code" : "special", "value" : false } } }
] })
Hope this $nin will solve your issues.
I insertd your docs into "so" collection
db.so.find({}).pretty();
{
"_id" : ObjectId("5489cd4f4cb16307b808d4b2"),
"name" : "test",
"data" : [
{ "code" : "name",
"value" : "Diego"
},
{ "code" : "nick",
"value" : "Darko"
},
{ "code" : "special",
"value" : true
}
]
}
{
"_id" : ObjectId("5489cd674cb16307b808d4b3"),
"name" : "another",
"data" : [
{"code" : "name",
"value" : "Antonio"
},
{ "code" : "nick",
"value" : "Tony"
}
]
}
don't contain a "data" item with code "special"
> db.so.find({"data.code":{$nin:["special"]}}).pretty();
{
"_id" : ObjectId("5489cd674cb16307b808d4b3"),
"name" : "another",
"data" : [
{ "code" : "name",
"value" : "Antonio"
},
{ "code" : "nick",
"value" : "Tony"
}
]
}
contains a "data" item with code "special" and value false
db.so.find({$and:[{"data.code":"special"},{"data.value":false}]}).pretty();