Printing the calculated distance in SQLAlchemy - postgresql

I am using Flask-SQLAlchemy with Postgres, Postgis and GEOAlchemy. I am able to sort entries in a table according to a point submitted by the user. I wonder how I could also return the calculated distance...
This is how I sort the items:
result = Event.query.order_by(func.ST_Distance(Event.address_gps, coordinates_point)).paginate(page, 10).items
for result in results:
result_dict = result.to_dict()
return result_dict
according to the users position (coordinates_point). I would like to add an entry in each result in the result_dict which also contains the distance that the item was ordered by. How do I do that? What does func.ST_Distance return?
I tried to add this in the for loop above:
current_distance = func.ST_Distance(Event.address_gps, coordinates_point)
result_dict['distance'] = current_distance
But that did not seem to work.

You can use column labels
query = Event.query.with_entities(Event, func.ST_Distance(Event.address_gps, coordinates_point).label('distance')).order_by('distance')
results = query.paginate(page, 10).items
for result in results:
event = result.Event
distance = result.distance
result_dict = event.to_dict()
result_dict['distance'] = distance

Related

Concatenate pymongo Cursor

How do you concatenate multiple pymongo Cursor? If not it is not possible, how do you take results from multiple Cursor and create a new one?
Example :
result1 = db[collection].find(query1)
result2 = db[collection].find(query2)
concat_result = result1 + result2 #something like that.
Update :
All answers here seems to take into account that the queries are in the same format. For example. query1 might get 2 documents between dates as query2 might sorts documents by categories and may be limited by a count of 5. $or is too homogeneous for what I need. After concatening those two queries, I need to sort them base on another key.
For further details, a class Printer needs to receive a pymongo.Cursor and only one and i'm stuck with this.
The easiest way is to use mongo $or operator like
db[collection].find({'$or': [query1, query2]})
Or if you have got to do this in python you
def concat_results(*results):
ids = set()
for result in results:
for v in result:
if v['_id'] not in ids:
ids.add(v['_id'])
yield v1
concat_result = list(concat_results(result1, result2))
yes the wise solution would be to use the $or as stated above.
if you wanted to do so in a pythonic way then you could:
a = [item for item in db[collection].find({filters},{select_fields})]
b = [item for item in db[collection].find({filters},{select_fields})]
c = []
for x,y in zip(a,b):
c += [x, y]

retrieve data from structure when entering one field value MATLAB

I have created a structure about patient. Its fields are name, age, etc. I want to be able to retrieve a patient's all info by entering its name or any other unique property. In other words, how can I find the patient's index? Thanks in advance.
patient(10).name = 'Chuck';
patient(10).age = 29;
patient(11).name = 'Sarah';
patient(11).name = 28;
Structures are not a good data type for doing what you want.
I suggest using a table. If you have your data in the structure already, call
patientTable = struct2table(patient);
Then, you get the index as:
chucksIndex = find( strcmp( patientTable.name, 'Chuck'))
And you get that patient's information as
patientTable(chucksIndex,:)
(note: if all you need the index for is lookup, you don't need to call find, the logical index from strcmp suffices).
Double-clicking the table in the workspace browser presents the data in an Excel-like fashion. The only thing you'll have to change in your code is accessing the data. Instead of
patient(10).name
patient(10).age
You write
patientTable.name{10}
patientTable.age(10)
If you do not want to use a table, you can get the index as:
chucksIndex = find(strcmp({patient.name},'Chuck'));
First, there is an error, it should be patient(11).name = 28;.
Here is a way this should work. I've started the indexes for Chuck and Sarah at 1.
patient(1).name = 'Chuck';
patient(1).age = 29;
patient(2).name = 'Sarah';
patient(2).age = 28;
% Assign to cell array
plist = {patient.name};
% Choose the name of a patient
choose_patient = 'Sarah';
% Find the chosen patient in the list
ix_patient = find(strcmp(plist, choose_patient))
% Get full entry for that patient
patient(ix_patient)

MongoDB Query advice for weighted randomized aggregation

By far I have encountered ways for selecting random documents but my problem is a bit more of a pickle.So here goes
I have a collection which contains say a 1000+ documents (products)
say each document has a more or less generic format of .Say for simplicity it is
{"_id":{},"name":"Product1","groupid":5}
The groupid is a number say between 1 to 20 denoting the product belongs to that group.
Now if my query input is something like an array of {groupid->weight} for eg {[{"2":4},{"7":6}]} and say another parameter n(=10 say) Then I need to be able to pick 4 random documents that belong to groupid 2 and 6 random documents that belong to groupid 7.
The only solution i can think of is to run 'm' subqueries where m is the array length in the query input.
How do I accomplish this an efficient manner in MongoDB using probably a Mapreduce.
Picking up n random documents for each group.
Group the records by the groupid field. Emit the groupid as key
and the record as value.
For each group pick n random documents from the values array.
Let,
var parameter = {"5":1,"6":2}; //groupid->weight, keep it as an Object.
be the input to the map reduce functions.
The map function, emit only those group ids which we have provided as the parameter.
var map = function map(){
if(parameter.hasOwnProperty(this.groupid)){
emit(this.groupid,this);
}
}
The reduce function, for each group, get random records based on the parameter object in scope.
var reduce = function(key,values){
var length = values.length;
var docs = [];
var added = [];
var i= 1;
while(i<=parameter[key]){
var index = Math.floor(Math.random()*length);
if(added.indexOf(index) == -1){
docs.push(values[index]);
added.push(index);
i++;
}
else{
i--;
}
}
return {result:docs};
}
Invoking map reduce on the collection, by passing the parameter object in scope.
db.collection.mapReduce(map,
reduce,
{out: "sam",
scope:{"parameter":{"5":1,"6":2,"n":10}}})
To get the dumped output:
db.sam.find({},{"_id":0,"value.result":1}).pretty()
When you bring the parameter n into picture, you need to specify the number of documents for each group as a ratio, or else that parameter is not necessary at all.

Accessing table data in different forms Matlab

I have T table as follows.
LastName = {'Smith';'Johnson';'Williams';'Jones';'Brown'};
Age = [38;43;38;40;49];
FirstName = {'Amanda' ;'Brenda';'Carl'; 'Denis'; 'Ethan'};
Something = {'String1' ;'String2';'String2'; 'String1'; 'String5'};
Weight = [176;163;131;133;119];
FavoriteColor = {'blue' ;'red' ;'yellow'; 'orange' ;'colorblind' };
T = table(Age,FirstName,Weight,FavoriteColor,Something,'RowNames',LastName)
T.FavoriteColor= categorical(T.FavoriteColor);
T.Something= categorical(T.Something);
when I use
A=T(:,5);
I get a variable A which is a table as well. But when I use
A=T.Something;
I get a variable A which is a categorical value like the ones is column Something. I want to use loops so I need to use the first one with indices but I want the result in the second one. What should I do?
Using a=T{:,5}; solved the problem.

Highcharts: Comparing 2 lines with different dates

I'm comparing 2 users of twitter on who receives the most tweets on a particular day, and put this in a line graph of Highcharts, the following mysql code I have:
<?php
require('mysql_connect.php');
$artist1 = $_POST['dj1'];
$artist2 = $_POST['dj2'];
$dates_result = mysqli_query($con,"SELECT DISTINCT(tweetDate) FROM tb_tweetDetails");
while ($row = mysqli_fetch_array($dates_result)) {
$dates[] = $row['tweetDate'];
}
$artist1_tweetsADay_result = mysqli_query($con,"SELECT tweetDate,COUNT('tweetIds') AS 'amountTweets' FROM tb_tweetDetails WHERE tweetId IN
(SELECT tweetId FROM tb_tweetLink LEFT JOIN tb_artists ON
(tb_tweetLink.artistId = tb_artists.artistId) where artistName = '$artist1') GROUP BY tweetDate");
while ($row = mysqli_fetch_array($artist1_tweetsADay_result)) {
$artist1_tweetsADay_date[] = "'" . $row['tweetDate'] . "'";
$artist1_tweetsADay_amount[] = $row['amountTweets'];
}
$artist1_tweetsADay_result = mysqli_query($con,"SELECT tweetDate,COUNT('tweetIds') AS 'amountTweets' FROM tb_tweetDetails WHERE tweetId IN
(SELECT tweetId FROM tb_tweetLink LEFT JOIN tb_artists ON
(tb_tweetLink.artistId = tb_artists.artistId) where artistName = '$artist2') GROUP BY tweetDate");
while ($row = mysqli_fetch_array($artist1_tweetsADay_result)) {
$artist2_tweetsADay_date[] = "'" . $row['tweetDate'] . "'";
$artist2_tweetsADay_amount[] = $row['amountTweets'];
}
?>
I use this to collect all the available dates I collected tweet data (so also from other then the selected 2 artists)
Then I get the amount of tweets the user received that day, together with the date.
This all works nicely, and the output is as I expected.
Now when I put it in the graph, I put the array of the dates, as the xAxis Categories.
And put the tweetAmount for both artists in the data inputs to create both lines.
The problem is:
Artist 1 has data on 06-04-2013,08-04-2013 & 10-04-2013
Artist 2 has data on 07-04-2013,08-04-2013, 09-04-2013 & 10-04-2013 (so everyday that actually is in my database)
Artist 2 would have his data of 07-04-2013 at 06-04-2013 (since that value comes first)
Artist 1 & 2 have 08-04-2013 under the categorie 07-04-2013 since that is the second available date.
etc. etc.
Is it possible I could use the dates array, to fix the arrays of the amount of tweets, so that every missing date would have 0 assigned to it so the line stays correct with the date.
The two things that I would do to accomplish this:
1) use a datetime x axis
2) while pulling the data from your table, create an array of every date returned in addition to the arrays you are already building. loop through the array of dates, and for each date, check the individual arrays for a value. if no value exists, create it.
You will then have two arrays with the same dates, and you can plot them on a datetime axis and not worry about category index matching.