PostGIS query with NodeJS, BookshelfJS and Knex - node.js

I'm on a project with NodeJS, BookshelfJS and ExpressJS.
My database is Postgres with Postgis installed.
My table 'organizations' has a 'lat_lon' geometry column.
I would like to query all the organization within a fixed radius of a specific lat/long point.
I tried something like this:
var organizations = await Organization.query(function (qb) {
qb.where('ST_DWithin(lat_lon, ST_GeomFromText("POINT(45.43 10.99)", 4326), 1000 )')
}).fetchAll()
and more combinations but it doesn't work.
It returns me an error
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: The operator "undefined" is not permitted
It seems it is expecting the operator inside the where condition but I'm already working on the 'lat_lon' column.
How can I fix it?
Thanks

Have you tried using knex.raw()?
var organizations = await Organization.query(function (qb) {
qb.where(knex.raw('ST_DWithin(lat_lon, ST_GeomFromText("POINT(45.43 10.99)", 4326), 1000 )'))
}).fetchAll()

I found that whereRaw was the solution that I was looking for when I encountered a similar situation.
Basic Example
If we have the following query using where
qb.where('id', 2')
The whereRaw equivalent is
qb.whereRaw('id = ?', [2])
As Applied to Situation from the Question
I believe that this is roughly equivalent to your query
qb.whereRaw('ST_DWithin(lat_lon, ST_GeomFromText("POINT(45.43 10.99)", 4326), 1000 )')
which could possibly be parameterized as
qb.whereRaw(
'ST_DWithin(lat_lon, ST_GeomFromText("POINT(?, ?)", 4326), ?)',
[45.43, 10.99, 1000]
)
if the Longitude, Latitude, or search radius were to change.

Related

How to write a WHERE prop FROM value TO value query in Nest JS TypeORM

I need to find posts from the Post table where price property is either more than 1 value or lower than 2 value, min-max price kind of a thing, how to write a query for that? What should I write into the options object?
const posts = await this.postRepo.find({
where: {
price: Between(1, 100),
},
});
Can you try this? Or else you can also use createQueryBuilder to write more complex queries.

How to actually query data from Firestore with GeoFirestore?

I'm trying to query documents near a given point in given radius in Firestore with using GeoFirestore for my node.js project. Firstly, I have a document in the database in this format:
My query code is like this:
// Create the GeoFirestoreQuery object
const geoQuery = geoFirestore.query({
center: new firebase.firestore.GeoPoint(latitute, longitude),
radius: 5,
query: (ref) => ref.where("d.available", "==", true)
});
The thing is that, I cannot figure out how to get the document from the query. I tried the code below, but it simply is not called at all.
// Fetch the nearest couriers
const onKeyEnteredRegistiration = geoQuery.on("key_entered", function(key, document, distance) {
console.log(key);
});
How can I return the document? What I am missing? Is my query and database structure matches? Is there any missing fields or issues? Or should I use another query instead of "key_entered"? Thanks for any help in advance.
I found the issue, it was about the database structure. I changed my structure as shown below and now it works perfectly.

"Missing required key 'Key' in params" in Get operation of Dynamo dB

I am writing Lambda function in node.js to getitems from dynamodB. Table is employee where emo_Id is the Partition key. Below is the code snippet I am writing:
var table = "Employee_Test";
var emp_Id=event.emp_Id;
var emp_Name=event.emp_Name;
var params = {
TableName: table,
KeyConditionExpression: "#eId = :Id",
ExpressionAttributeNames:{
"#eId": "emp_Id"
},
ExpressionAttributeValues: {
":Id":emp_Id
}}
The error I am getting is :
"message": "Missing required key 'Key' in params",
"code": "MissingRequiredParameter",
I know the resolution of the error is to add:
Key:{
"emp_Id": emp_Id,
} to the code. But If I have to query the employees who have joined after a particular date then I cannot provide emp_Id as a parameter.
In the AWS release notes I have found that we can disable parameter validation,
https://aws.amazon.com/releasenotes/6967335344676381 I tried this but this is also not working.
Can somebody please help?
Thanks
Shweta
I was hit with a same error when querying the secondary indexes. Turns out that I was using the wrong API. Confused between getItem and Query.
I ran into this when I first started with DynamoDb. Such an annoying error. Turns out I had accidentally used the .get method, from a previous working getById example, instead of the .query method.
In short, you may just need to change this ...
const response = await db.get(query).promise();
... to this ...
const response = await db.query(query).promise();
Add a Global Secondary Index to your table to enable lookups by start date. First, change your item creation code (PutItem) to add an attribute representing the month and year an employee joined, like joinYearMonth=201612. Second, scan your table to find items that do not already have this attribute and add it. Third, create a Global Secondary Index with a partition key of joinYearMonth and a sort key of joinTimestamp. This way, you can issue query requests on the GSI for the years and months you require to find those that joined.

Loopback query which compares field values

Say i have the following Scheme
Product: {
Quantity: Number,
SelledQuantity: Number
}
Would it be possible to write a query where all the results returned are where Quantity=SelledQuantity?
If so, is there a way to use it when doing a populate? (Perhaps inside the match field in the opts object ?)
I use mysql connector.
yes as I understood your problem you can do this by following rest call.
http://localhost:3000/api/products?filter[where][SelledQuantity]=n
this will give you the desired results.
This question is more related to MySQL query. But you can achieve it by javascript as follows:
Product.find({}, fuction(err, products) {
if(err) throw err;
//considering products as array of product. Otherwise you can get to depth for array of product.
var filteredProducts = products.filter(function(p1) {
return p1.Quantity === p1.SelledQuantity;
});
//Your desired output
console.log(filteredProducts);
});
This will be slow but will work for smaller database size. For more optimized answer, ask the question in mysql section with respect to database and table structure.

Mongoose query with undefined

I am trying to use mongoose to construct a query equivalent to this SQL:
select * from problems where tutorialNumber is not null
I've tried:
var q = Problem.find().where('tutorialNumber').ne(undefined);
q.exec(callback);
It returned an error: CastError: Cast to string failed for value "undefined" at path "tutorialNumber"
What is the right way to do that?
Thanks for the replies. I found another way to do it:
var q = Problem.find().exists('tutorialNumber', true);
q.exec(callback);
There are several syntax options. I believe your code is OK other than you should use null instead of undefined. I prefer the style that is a little closer to normal mongo shell:
Problem.find({tutorialNumber: {$ne: null}}, callback);
or you can do
Problem.find().ne('tutorialNumber', null).exec(callback);
But I believe the way you are using where and ne are also correct.
However, the CastError can mean there's a problem in your schema (could be trying to nest models instead of nesting schema).

Resources