MongoDB - Update a field only if it doesn't exist - mongodb

I found a question similar to mine regarding updating a document if a certain field does not exist. But in the question, it is not an array of documents like what I have
{
"_id" : ObjectId("5a5f814487c320156094c144"),
"sender_id" : "123",
"iso_number" : "ABC-DEF-123",
"subject" : "Sample Memo",
"content" : "This is a sample memorandum sent through postman.",
"recipients" : [
{
"faculty_number" : 222,
"_id" : ObjectId("5a5f814487c320156094c146"),
"status" : "Sent"
},
{
"faculty_number" : 111,
"_id" : ObjectId("5a5f814487c320156094c145"),
"status" : "Sent"
}
],
"memo_created" : ISODate("2018-01-17T17:00:52.104Z"),
"__v" : 0
}
I'm trying to attach a memo_seen to recipient with faculty_number 111, I'm using the query.
db.getCollection('memos').update({"_id": id, "recipients.faculty_number": faculty_number, "recipients.$.memo_seen": {$exists: false}}, {$set: {"recipients.$.memo_seen": timestamp}})
The timestamp should not update when I repeat the query. Can someone help me out? Been stuck for quite some time now.

Related

mongodb lookup giving empty array

BED_MAST this is my one collection bed_mast contains WARD_ID and want to perform join to my other collection with is WARD_MAST given below.
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46376"),
"Bed_id" : "bd-10",
"WARD_ID" : "4",
"OCCUPIED" : "0",
"BED_TYPE" : "single AC"
}
{
"_id" : ObjectId("5e53c95a26b0e5ad0fb46377"),
"Bed_id" : "bd-11",
"WARD_ID" : "1",
"OCCUPIED" : "0",
"BED_TYPE" : "single Non AC"
}
WARD_MAST this is my WARD_MAST having ward_id. but while I am putting lookup I am not getting any data.
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46544"),
"patient_id" : null,
"ward_id" : 1,
"total_beds" : 55,
"ward_name" : "Ward 1"
}
{
"_id" : ObjectId("5e53c95d26b0e5ad0fb46545"),
"patient_id" : null,
"ward_id" : 2,
"total_beds" : 63,
"ward_name" : "Ward 2"
}
MY query is
db.BED_MAST.aggregate([{$lookup:{'from':"WARD_MAST",'localField':"WARD_ID",'foreignField':"ward_id",'as':"lookup_value"}}]).pretty()
output: I have confirmed the data by running this query to MySQL there it is working fine
{
"_id" : ObjectId("5e53c95b26b0e5ad0fb46388"),
"Bed_id" : "bd-28",
"WARD_ID" : "6",
"OCCUPIED" : "0",
"BED_TYPE" : "NICU",
"lookup_value" : [ ]
}
SAMPLE VALUES DATA IS GIVEN ALL DATA IS NOT POSSIBLE TO GIVE. I know it was asked 1000 times but not able to resolve this question. tried to solve with lookup. but it showing blank space. Is anything I am missing.
The problem is BED_MAST collection's WARD_ID has string values and WARD_MAST collection's ward_id has Number values.

Explanation of mongo query with OR condition

I have this data in my db
{ "_id" : ObjectId("5c89da093180684aba34c5b7"), "name" : "Allen", "age" : 24, "nicknames" : [ "kanky" ], "siblings" : [ ] }
{ "_id" : ObjectId("5c89da4b3180684aba34c5b8"), "name" : "Sonata", "age" : "30" }
{ "_id" : ObjectId("5c89da8f3180684aba34c5b9"), "name" : "Kaushik", "age" : "20" }
{ "_id" : ObjectId("5c89da8f3180684aba34c5ba"), "name" : "Stuart", "age" : "24" }
{ "_id" : "5c89da093180684aba34c5b7", "name" : "Allen", "age" : 24 }
When I run this query db.people.find({$or: [{name:"Allen"}, {age:24}]}), it doesn't give the entry with name : Stuart which has age : 24.
But if I run this query db.people.find({$or: [{name:"Stuart"}, {age:24}]}), it works as intended.
Can anyone explain how does this work? I am starting with mongodb, so mightbe a very basic question.
Thanks
You have different schema types for age in different documents. For Allen you are using a number data type for age and for Stuart you are using a string to store age. I think thats the problem.
Try running this:-
db.people.find({$or: [{name:"Allen"}, {age: "24" }]})
You will get Stuart with this query. I don't see anything else wrong here except for different data types.

Mongodb + Mongoose: trying to add a sub-sub-item

Does this makes any sense when trying to add a sub-sub-item? (I'm new to mongo - be merciful :-))
question = db.questions.findOne({_id: ObjectId("529c5d44211c9a8c11000006")})
question.answers[0].votes.insert(...)
When I run this from the mongo console the result is an error saying [object object] does not have the method insert.
I have the following mongoDB Question Schema.
{
"__v" : 2,
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d44211c9a8c11000006"),
"answers" : [
{
"postDate" : ISODate("2013-12-02T10:14:19.060Z"),
"postDateText" : "15min ago",
"authorEmail" : "guys#pix.com",
"authorName" : "guys#pix.com",
"body" : "You need magic powder",
"isWinner" : false,
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d7b211c9a8c11000008"),
"votes" : [
{
"voteType" : "up",
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d5b211c9a8c11000007")
}
]
}
],
"authorEmail" : "guys#wix.com",
"authorName" : "guys#wix.com",
"body" : "I'm trying to fly...\n\n<pre class=\"brush: js;\">\nfunction logName(name) {\n console.log(name);\n}\n</pre>",
"isResolved" : false,
"postDate" : ISODate("2013-12-02T10:13:24.235Z"),
"tags" : [
"fly"
],
"title" : "How do I fly?",
"views" : [],
"votes" : [
{
"voteType" : "up",
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d5b211c9a8c11000007")
}
]
}
I'm trying, given a questionId and an answerId to add a vote to the votes array (which is inside the answer). I can't seem to do it. Help?
insert is for adding whole new documents; when you just want to add a new element to an array field of an existing document, you can use update along with an operator like $push.
So, in the shell you would use something like this:
db.questions.update(
{_id: ObjectId("529c5d44211c9a8c11000006")},
{'answers.0.votes': {$push: voteToPush}})

Array query and return

My first adventure into Mongo. Please save me some time by answering the following. This is the schema.
"_id" : 1,
"FullName" : "Full Name",
"Email" : "email#email.com",
"FacebookId" : NumberLong(0),
"LastModified" : ISODate("2012-04-11T09:26:10.955Z"),
"Connections" : [{
"_id" : 7,
"FullName" : "Fuller name",
"Email" : "connections#email.com",
"FacebookId" : NumberLong(0),
"LastModified" : ISODate("0001-01-01T00:00:00Z")
},
....
Given an id of a single top user, i'd like to return all of the Emails in the Connections array, and preferably, just the emails. What's the querystring? Much obliged!
You can't get only values from the sub-objects in MongoDB.
If you do a query like this:
db.test.find({"_id": 1}, {"Connections.Email":1});
you will get this kind of response:
{
"_id": 1,
"Connections" : [ {"Email":"connections#email.com"},
{"Email":"foo#example.com"} ]
}
This is the closest you can get with a simple query and field selection from MongoDB.
You can then filter out the e-mails values in your code with a simple foreach.

Mongodb save/upsert using C# drivers, continuous array adds and field updates to same doc

I need some ideas/tips for this. Here is a sample document I am storing:
{
"_id" : new BinData(0, "C3hBhRCZ5ZFizqbO1hxwrA=="),
"gId" : 237,
"name" : "WEATHER STATION",
"mId" : 341457,
"MAC" : "00:00:00:00:00:01",
"dt" : new Date("Fri, 24 Feb 2012 13:59:02 GMT -05:00"),
"hw" : [{
"tag" : "Weather Sensors",
"snrs" : [{
"_id" : NumberLong(7),
"sdn" : "Wind Speed"
}, {
"_id" : NumberLong(24),
"sdn" : "Wind Gust"
}, {
"_id" : NumberLong(28),
"sdn" : "Wind Direction"
}, {
"_id" : NumberLong(31),
"sdn" : "Rainfall Amount"
}, {
"_id" : NumberLong(33),
"sdn" : "Rainfall Peak Amount"
}, {
"_id" : NumberLong(38),
"sdn" : "Barometric Pressure"
}],
"_id" : 1
}]
}
What I am currently doing is using the C# driver and performing a .Save() to my collection to get upsert, however, what I want is kinda a hybrid approach I guess. Here are the distinct operations I need to be able to perform:
Upsert entire document if it does not exist
Update the dt field with a new timestamp if the document does exist
For the hw field, I need several things here. If hw._id exists, update its tag field as well as handling the snrs field by either updating existing entries so the sdn value is updated or adding entirely new entires when _id does not exist
Nothing should ever be removed from the hw array and nothing should ever be removed from the snrs array.
A standard upsert does not appear to get me what I am after, so I am looking for the best way to do what I need with as few roundtrips to the server as possible. I am thinking some of the $ Operators may be what I am needing here, but just need some thoughts on how best to approach this.
The gist of what I am doing here is keeping an accumulating, historical document of snrs entries with the immediate current value as well as retaining any historical entries in the array even though they are no longer "alive", being reported, etc. This allows future reporting on things that no longer exist in current time, but were at some point in the past. _id values are application-generated, globally unique across all documents, and never change after initial creation. For example, last week "Wind Speed" was being reported, but this week it is not. It's _id value, however, will not change if "Wind Speed" starts reporting again. Follow?
Clarifications or more detail can be provided if needed.
Thanks.
By changing the structure of your document from embedded arrays to subdocuments key'ed by the _ids you can do this.
e.g.
{
"MAC" : "00:00:00:00:00:01",
"_id" : 1,
"dt" : ISODate("2012-02-24T18:59:02Z"),
"gId" : 237,
"hw" : {
"1" : {
"snrs" : {
"1" : "Wind Speed",
"2" : "Wind Gust"
},
"tag" : "Weather Sensors"
}
},
"mId" : 341457,
"name" : "WEATHER STATION 1"
}
I created the above document by the following upsert
db.foo.update(
{_id:1},
{
$set: {
"gId" : 237,
"name" : "WEATHER STATION 1",
"mId" : 341457,
"MAC" : "00:00:00:00:00:01",
"dt" : new Date("Fri, 24 Feb 2012 13:59:02 GMT -05:00"),
"hw.1.tag" : "Weather Sensors",
"hw.1.snrs.1" : "Wind Speed",
"hw.1.snrs.2" : "Wind Gust"
}
},
true
)
Now when I run
db.foo.update(
{_id:1},
{
$set: {
"dt" : new Date(),
"hw.2.snrs.1" : "Rainfall Amount"
}
},
true
)
I get
{
"MAC" : "00:00:00:00:00:01",
"_id" : 1,
"dt" : ISODate("2012-03-07T05:14:31.881Z"),
"gId" : 237,
"hw" : {
"1" : {
"snrs" : {
"1" : "Wind Speed",
"2" : "Wind Gust"
},
"tag" : "Weather Sensors"
},
"2" : {
"snrs" : {
"1" : "Rainfall Amount"
}
}
},
"mId" : 341457,
"name" : "WEATHER STATION 1"
}