Setting Relationships in MongoDB with ObjectID only - javascript

In MongoDB the relationships can be are set by using the _id of the parent in the child object example In the two objects written below the relationship is set between the two by the owner attribute.
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"name": "Tom Hanks",
"contact": "987654321",
"dob": "01-01-1991"
}
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"owner": ObjectId("52ffc33cd85242f436000001"),
"address": [
{
"building": "22 A, Indiana Apt",
"pincode": 123456,
"city": "Los Angeles",
"state": "California"
},
{
"building": "170 A, Acropolis Apt",
"pincode": 456789,
"city": "Chicago",
"state": "Illinois"
}
]
}
My concerns is to take a decision between two collection based on _id attribute, if I use the _id attribute in the child collection should be it of type ObjectID (as shown in the example above) or should the child object use the _id vale from the parent as a string type (eg "owner": "52ffc33cd85242f436000001"),
what should be the best practice with some pons and cons.

Related

Mongoose - find documents that match one or more conditions

I have three documents that look like this
{
"name": "X1",
"location": {
"country": "Ireland",
"state": "Dublin",
},
},
{
"name": "X2",
"location": {
"country": "Ireland",
"state": "Dublin",
"address": ""
},
},
{
"name": "C3",
"location": {
"country": "United States of America",
"state": "California",
"address": "San Jose"
},
I am trying to implement a filtering functionality to show documents based on multiple locations.
so, the endpoint URL looks like this for example http://localhost:3000/api/companies/stacks?state[]=Dublin&country[]=United%20States%20of%20America
So, it should return the three documents that are shown above, yet it only returns this document
{
"name": "C3",
"location": {
"country": "United States of America",
"state": "California",
"address": "San Jose"
},
Here is the source code, I am using Mongoose mainly.
//Filtering by location
if ('country' in req.query) {
const countries = [...country]
conditions['location.country']={$in:countries}
}
if ('state' in req.query) {
const states = [...state]
conditions['location.states'] = { $in: states }
}
const doc = await model
.find(conditions)
.sort({ p: -1, _id: 1 })
.lean()
.exec()
I understood that it returns the document that matches the country parameter, but I don't understand why it doesn't also fetch the other documents that has Dublin in states?
Edit: I also tried to use $or operator like that
find({
$or:[
{'location.country':'United States of America'},
{'location.states':'Dublin'}
]
})
Yet it also, returned the document that matches the country only. I thought about using aggregates but I am not sure if it is going to help me in my case?
Thanks in advance.

How to Partially Update a DynamoDB Table?

We're having a lot of trouble doing a partial update in DynamoDB.
Trying to use best practices in NoSQL by using aggregates instead of entities so our data looks a bit like this:
[
{
"userLogin": {
"ipAddress": "123.222.121.1234",
"lastLogin": "2017-10-16T17:38:59.818Z",
"userAgent": "bob",
"geoLocation": "lat-121 long-312"
},
"addresses": {
"billingAddress": {
"streetName": "york street",
"province": "ontario",
"city": "toronto",
"streetNumber": "18",
"postalCode": "m5a2v7"
},
"businessAddress": {
"streetName": "york street",
"province": "ontario",
"city": "toronto",
"streetNumber": "18",
"postalCode": "m5a2v7"
},
"mailingAddress": {
"streetName": "york street",
"province": "ontario",
"city": "toronto",
"streetNumber": "18",
"postalCode": "m5a2v7"
},
},
"paymentTransaction": {
"orderId": 5,
"amount": 75,
"transactionTimestamp": "2017-10-16T17:38:59.818Z"
},
"userId": "00uc4sxyi7gfQoFum0h7",
"phoneNumbers": {
"workNumber": "647-123-1234",
"homeNumber": "647-321-4321"
},
"userProfile": {
"role": "admin",
"verifiedTimeStamp": "2017-10-16T17:38:59.818Z",
"termsConditionTimeStamp": "2017-10-16T17:38:59.818Z",
"verified": "TRUE",
"createdTimeStamp": "2017-10-16T17:38:59.818Z",
"termsConditionVersion": "1.0",
"email": "kyle.truong#test.io"
}
}
]
All we want to do is make a request with a body like this:
PUT /api/user-profiles/00uc4sxyi7gfQoFum0h7
body: {
"userLogin": { "lastLogin": "2017-12-16T17:38:59.818Z" }
}
and have it update the one attribute in the User table.
The updateItem API seems to require defining the attributes you want to update before updating them, but we want it be more flexible and dynamic based on the body of the request.
This thread seems to say it's not possible:
How to update multiple items in a DynamoDB table at once
If so, what's the best way to go about updating just a partial attribute object within an item in DynamoDB?
In dynamoDB if your userLogin is a map type then you can update the value of lastLoginkey. In Java below code may help. Here column name would be userLogin and newKey would be lastLogin. Full code snippet can be found here
UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey(primaryKey,primaryKeyValue).withReturnValues(ReturnValue.ALL_NEW).
withUpdateExpression("set #columnName." + newKey + " = :columnValue").
withNameMap(new NameMap().with("#columnName", updateColumn)).
withValueMap(new ValueMap().with(":columnValue", newValue)).withConditionExpression("attribute_exists("+ updateColumn +")");
table.updateItem(updateItemSpec);

How to create markers to group AngularJS ng-repeat output by date (month)?

For a project I'm doing I'm outputting an array of data using ng-repeat from AngularJS and am trying to group the output by Month. There's no need to orderBy, since the data I get is already sorted, I just need to group it by Month.
The data I get from the API looks similar like this:
{"userinfo": [{
"date": "1305838800000",
"name": "john",
"lastname": "dough",
"city": "",
"province": "noord-holland",
"device": "macbook",
"phone": "iphone",
"provider": "t-mobile"
}, {
"date": "1305838800000",
"name": "john",
"lastname": "",
"city": "amsterdam",
"province": "noord-holland",
"device": "macbook",
"phone": "iphone",
"provider": "vodafone"
},{
"date": "1305838800000",
"name": "john",
"lastname": "",
"city": "amsterdam",
"province": "noord-holland",
"device": "macbook",
"phone": "iphone",
"provider": "t-mobile"
}, {
"date": "1305838800000",
"name": "john",
"lastname": "",
"city": "amsterdam",
"province": "noord-holland",
"device": "macbook",
"phone": "iphone",
"provider": "vodafone"
}]}
In here the field field would be the epoch date of the date I want to group by.
Any help on this grouping matter would be appreciated.
While this functionality will not land in AngularJS core:
https://github.com/angular/angular.js/issues/1649
You can either go with re-grouping an array into a map object on scope (Underscore.JS's groupBy is a nice example) or creating a new groupBy filter/use existing ones like:
https://github.com/samstokes/ng-group/
One plus for regrouping on scope - it will only happen once, while filters are re-evaluated on each digest.
There's no support for this kind of grouping in built-in angular directives. You'll need to create a copy of your model that you get from the server (a new collection), "manually" group the objects in the according months (by date) and then loop over that copy (in the view by using ng-repeat) instead of looping over the original model.

Displaying Dictionary in Javascript Object

I'm returning this response from my server:
callback({"City": "Miami", "State": "FL", "Street": "9th Street", "Name": "Big 12", "Zip": "65201", "Lat": -48.219999999999999, "Telephone": "5732168906", "Long": 32.0, "Events": "[{\"End Time\": \"2011-01-22 23:36:31\", \"Name\": \"Margaritas\", \"Start Time\": \"2011-01-22 15:36:31\"}, {\"End Time\": \"2011-01-22 19:36:39\", \"Name\": \"Dollar Bottles\", \"Start Time\": \"2011-01-22 15:36:39\"}, {\"End Time\": \"2011-01-23 23:36:31\", \"Name\": \"All You Can Drink\", \"Start Time\": \"2011-01-23 15:36:31\"}]"})
Here is where I'm attempting to parse the response and display it within my "tonight-list". With data.Events, I get the entire array of dictionaries displayed on screen.
function callback(data){
console.log(data);
$("#tonight-list").append("<li role='option' tabindex='0' class='ui-li ui-li-static ui-btn-up-c'>Starts:" +
data.Events +
"<li>");
However, I cannot figure out how to access each element (Start Time, End Time, Name, etc.). When I try data.Events[0], it gives me just the first character from data.Events.
How do I access each dictionary key in the array of Events? I just cannot figure out the syntax - it would be nice if I could see all the options on this object type. Thanks for the help in advance!
Make the Events in the JSON response a real array instead of a string, then you can use it like this:
var obj = JSON.parse(reponseText);
var event = obj.Events[0];
alert(event["End Time"]); // hurray
JSON response
callback({
"City": "Miami",
"State": "FL",
"Street": "9th Street",
"Name": "Big 12",
"Zip": "65201",
"Lat": -48.219999999999999,
"Telephone": "5732168906",
"Long": 32.0,
"Events": [{
"End Time": "2011-01-22 23:36:31",
"Name": "Margaritas",
"Start Time": "2011-01-22 15:36:31"
},
{
"End Time": "2011-01-22 19:36:39",
"Name": "Dollar Bottles",
"Start Time": "2011-01-22 15:36:39"
},
{
"End Time": "2011-01-23 23:36:31",
"Name": "All You Can Drink",
"Start Time": "2011-01-23 15:36:31"
}]
})​;
JSON dude! just return valid JSON from your server and use evalJSON. Then you can access each object via their corresponding keys.
edit:
basically do,
data.responseText.evalJSON();

Convert json to a string using jquery

I have a nested json. I want to post it as a form input value.
But, seems like jquery puts "Object object" string into the value.
It seems easier to pass around the string and convert into the native form I need, than dealing with json as I don't need to change anything once it is generated.
What is the simplest way to convert a json
var json = {
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" }
],
"newSubscription": false,
"companyName": null
};
into its string form?
var json = '{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" }
],
"newSubscription": false,
"companyName": null
}'
Following doesn't do what I need:
Json.stringify()
jQuery doesn't have a method for JSON stringifying native objects. You will need json2.js which will provide the JSON.stringify() method to browsers that don't already support it.

Categories

Resources