extracting particular values from JSON - javascript

I am using Google Distance Matrix API and the response I got was in JSON:
{
"destination_addresses" : [ "Chandigarh, India" ],
"origin_addresses" : [ "Delhi, India" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "244 km",
"value" : 243506
},
"duration" : {
"text" : "3 hours 54 mins",
"value" : 14069
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I want to get the following values from JSON, destination_address, origin_address, distance, duration, and status. This is my code that I am trying out:
import requests as r
import json
a = r.get("https://maps.googleapis.com/maps/api/distancematrix/json?origins=Delhi&destinations=Chandigarh&key=key")
#text form of a
tfa = a.text
print(tfa)
with open('data.json','w') as outfile:
json.dump(tfa,outfile)
json_data = json.loads(tfa)
print(json_data["destination_addresses"])
print(json_data["origin_addresses"])
print(json_data["rows"][0]["elements"][0]["distance"])
print(json_data["rows"]["elements"]["duration"])
The output that I am receiving gives me destination origin and distance, but I get an error when I try to grab duration, also the values inside the distance are printed as 'text':'244km','value':23432, but I only want to get the values not their labels. Is there any way to do that? Also is it possible to limit the values extracted inside the distance element (because I only want the text not the value)?

print(json_data["rows"][0]["elements"][0]["distance"]["value"])
Adding ["value"] to your current code will only show the value.
print(json_data["rows"]["elements"]["duration"])
You try to get something from the same level as the distance but you forget the [0] in this line. You can basically copy and paste the code that prints the distance value but replace distance by duration:
print(json_data["rows"][0]["elements"][0]["duration"]["value"])

Related

Mongo not creating all docs in array and not giving errors

I have a long array of docs to create. When I create them I get no errors.
const docsJson =[some array of json of docs to create]
const orders = await MySchema.create(ordersJSON);
// orders.length returns the same number of docs as docsJson
But when I search for the new docs, only some were created.
const actualOrdersCreated = await MySchema.find({ _id: { $in: orders.map((p) => p._id) } });
// actualOrdersCreated.length returns less docs than in docsJson
What's causing this?
I think your data is to large.
The maximum BSON document size is 16 megabytes.
Reference: https://www.mongodb.com/docs/manual/reference/limits/
This was due to having a ttl (time to live) index on one mongo database and not the other. I was copying docs over from a database. The index on the first database was:
$ mongo "mongodb+srv://....database-1-url"
>> db.myschema.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"paidOn" : 1
},
"name" : "paidOn_1",
"background" : true
}
]
But the database I was working with had expireAfterSeconds.
$ mongo "mongodb+srv://....database-2-url"
>> db.myschema.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"expireAt" : 1
},
"name" : "expireAt_1",
"background" : true,
"expireAfterSeconds" : 86400
},
{
"v" : 2,
"key" : {
"paidOn" : 1
},
"name" : "paidOn_1",
"background" : true
}
]
So mongo was deleting the new docs where the expireAt field had an old date.
To fix it I ran await Order.syncIndexes(); in a script. This cleared the index to [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" } ]. This is fine for my purpose. But the index isn't the same as the 1st database. The paidOn key is no longer indexes.
What I thought helped but didn't
At first I thought the issue was due to the large size of the jsonDocs.
I had objects with fields that had large base64 strings for images. These were placeholders, supposed to be replaced with http urls for the images.
After I removed the base64 strings I was able to upload the documents. I thought this helped but it was just speeding things up. It takes 1 minute for mongo to check up on expired docs.

Robmongo - aggregate values distinct by other value\cloumn

I'm new to robmongo and I received an assignment to write some queries.
let say I have a collection that each key has some values for example value of "userId" and value of "deviceModel".
I need to write a query that shows for each device model how many users has this device.
this is what I got so far:
db.device_data.aggregate([ {"$group" : {_id:"$data.deviceModel", count:{$sum:1}}}])
The problem is that this aggregate for each device the number of keys it appears.
{
"_id" : { "$binary" : "AN6GmE7Thi+Sd/dpLRjIilgsV/4AAAg=", "$type" : "00" },
"auditVersion" : "1.0",
"currentTime" : NumberLong(1479301118381),
"data" : {
"deviceDesign" : "bullhead",
"loginType" : "GOOGLE",
"source" : "SDKLoader",
"systemUptimeMillis" : 137652880.0,
"simCountryIso" : "il",
"networkOperatorName" : "Cellcom",
"hasPhonePermission" : true,
"deviceIdentifier" : "353627074839559",
"sdkVersion" : "0.7.939.2016-11-14.masterDev",
"brand" : "google",
"osVersion" : "7.0",
"osVersionIncremental" : "3239497",
"deviceModel" : "Nexus 5X",
"deviceSDKVersion" : 24.0,
"manufacturer" : "LGE",
"sdkShortBuildDate" : "2016-11-14",
"sdkFullBuildDate" : "Mon Nov 14 22:16:40 IST 2016",
"product" : "bullhead"
},
"timezone" : "Asia/Jerusalem",
"collectionAlias" : "DEVICE_DATA",
"shortDate" : 17121,
"userId" : "00DE86984ED3862F9277F7692D18C88A#1927cc81cfcf7a467e9d4f4ac7a1534b"}
this is an example of how one key locks like.
The below query should give you distinct count of userId for a deviceModel. I meant if a same userId present for a deviceModel multiple items, it will be counted only once.
db.collection.aggregate([ {"$group" : {_id:"$data.deviceModel", userIds:{$addToSet: "$userId"}}
},
{
$unwind:"$userIds"
},
{
$group: { _id: "$_id", userIdCount: { $sum:1} }
}])
Unwind:-
Deconstructs an array field from the input documents to output a
document for each element.
In the above solution, it deconstructs the userId array formed on the first pipeline.
addToSet:-
Returns an array of all unique values that results from applying an
expression to each document in a group of documents that share the
same group by key.
This function ensures that only unique values are added to an array. In the above case, the userId is added to an array in the first pipeline.

Accessing Child in JSON Object

I have a JSON
{
"destination_addresses" : [ "14 Mission St, San Francisco, CA 94105, USA" ],
"origin_addresses" : [ "23 Mission St, San Francisco, CA 94103, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "1.3 mi",
"value" : 2060
},
"duration" : {
"text" : "7 mins",
"value" : 444
},
"duration_in_traffic" : {
"text" : "6 mins",
"value" : 344
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I have been attempting to access the "text" value of duration_in_traffic and to store that value into a variable. For some reason I am getting the value to be undefined.
var hold = JSON.parse(body.rows.elements.duration.text);
Why cannot I access the child like this?
You have nested arrays, so you need to access the elements in the arrays by their index.
var hold = body.rows[0].elements[0].duration_in_traffic.text;
you need to parse the JSON string (if it is a string) first, then you can access it ... assuming body is the var that holds the string, you would do
var hold = JSON.parse(body).rows[0].elements[0].duration.text;
or
var obj = JSON.parse(body);
var hold = obj.rows[0].elements[0].duration.text;
JSON.parse does not parse part of a json string. if your json string is store in body for example, you need to parse it first:
var jsonObj = JSON.parse(body);
This will give you a javascript object to work with, then you can access the properties of the object as you have tried to do.
var hold = body.rows[0].elements[0].distance.text; //similar to #js91
Hope that helps!

How to access a part of a JSON file

Im trying to access some data and keep getting errors no matter what I try. Please help.
"rain":{"3h":13.625} is the part of the JSON file I am trying to access.
Here is what I have tried:
var currentRain = data.rain.3h; Which is most logical as it worked before but the number is what is giving the error.
var currentRain = data.rain["3h"];
var currentRain = data.rain[0]["3h"];
var currentRain = data.rain["3h"][0];
UPDATE:
This is the JSON payload:
{ "base" : "stations",
"clouds" : { "all" : 92 },
"cod" : 200,
"coord" : { "lat" : -33.850000000000001,
"lon" : 151.22
},
"dt" : 1429558616,
"id" : 6619279,
"main" : { "grnd_level" : 1024.97,
"humidity" : 100,
"pressure" : 1024.97,
"sea_level" : 1031.0999999999999,
"temp" : 288.77699999999999,
"temp_max" : 288.77699999999999,
"temp_min" : 288.77699999999999
},
"name" : "City of Sydney",
"rain" : { "3h" : 13.625 },
"sys" : { "country" : "AU",
"message" : 0.0101,
"sunrise" : 1429474880,
"sunset" : 1429514809
},
"weather" : [ { "description" : "heavy intensity rain",
"icon" : "10n",
"id" : 502,
"main" : "Rain"
} ],
"wind" : { "deg" : 157.5,
"speed" : 8.3200000000000003
}
}
You'll need to use ["bracket notation"] to access this, since "3h" begins with a number. As MDN explains:
An object property name can be any valid JavaScript string, or anything that can be converted to a string, including the empty string. However, any property name that is not a valid JavaScript identifier (for example, a property name that has a space or a hyphen, or that starts with a number) can only be accessed using the square bracket notation.
This is the correct JSON:
{
"rain": {
"3h": 13.625
}
}
First you need to parse it and transform into an object:
var jsonToObject = JSON.parse('{"rain":{"3h":13.625}}');
You can now access it like this:
jsonToObject.rain["3h"]
Just use data["rain"]. If you need to parse it first do JSON.parse(data) and then data["rain"].
OUTPUT
console.log(data["rain"]);
> { '3h': 13.625 }
...keep in mind that will return an Object.

The shortest path between two addresses

Using google map, you can actually get the different possible routes between two addresses, also you get the length of every possible route.
I'm now working on a website with google map, i want to calculate the shortest path between two different addresses same as google map does. then get the path length back as javascript variable.
You can use these function:
google.maps.geometry.spherical.computeDistanceBetween (latLng1, latLng1);
The arguments are two LatLng objects.
Make sure you include:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
I found it, it can be calculated using google map api called Distance Matrix it returns a json response containing The recommended path's length and Duration.
{
"destination_addresses" : [ "Témara, Maroc" ],
"origin_addresses" : [ "Rabat, Maroc" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "13,6 km",
"value" : 13620
},
"duration" : {
"text" : "23 minutes",
"value" : 1358
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
This should work fine:
function getDistance()
{
var url="http://maps.googleapis.com/maps/api/distancematrix/json?origins=rabat&destinations=temara&mode=driving&language=fr-FR&sensor=false";
var def = new jQuery.Deferred();
$.getJSON(url,function(json)
{
if (json.status=="OK")
{
var distance=json.rows[0].elements[0].distance.text;
}
def.resolve(distance);
});
return def.promise();
}
$.when(getDistance()).then(function(distance){
alert(distance);});
Demo

Categories

Resources