Я создал Aqueduct API с базой данных PostgresSql, и я пытаюсь запрашивать пользователей поблизости от местоположения (ограничено радиусом). Моя проблема состоит в том, что функция, которая вычисляет расстояние, является хранимой процедурой (для оптимизации этой операции), но у меня есть проблемы с использованием этой хранимой процедуры базы данных. Я нашел решение с помощью предиката запроса (см. Код ниже), но теперь моя проблема: как сослаться на столбец таблицы и передать его в процедуру? (в моем случае r.lat и r.long должны ссылаться на столбцы lat и long в текущей проверенной записи таблицы)
Код контроллера: Примечание (в моем случае r.lat и r.long должны ссылаться на lat и длинные столбцы в текущей проверенной записи таблицы)
@Operation.get()
Future<Response> getRequests({
@Bind.query("nearby_location") Map<String, double> location,
@Bind.query("parent_id") int parentID,
@Bind.query("status_id") int statusID,
@Bind.query("active") bool active,
@Bind.query("radius") double radius = 1,
}) async {
final query = Query<HelpRequest>(context);
if (statusID != null) {
query.where((n) => n.status).identifiedBy(statusID);
}
if (active != null) {
query.where((n) => n.active).equalTo(active);
}
if (location != null && statusID != null) {
query.predicate = QueryPredicate(
"parent_id IS NULL "
"AND status_id = @status_id "
"AND active = @active "
"AND CalculateDistance(r.lat, r.long, @lat, @long) < @radius",
{
'radius': radius,
'lat': location['lat'],
'long': location['long'],
'status_id': statusID,
'active': active
});
}
query..join(object: (r) => r.helpTopic)..join(object: (r) => r.status);
return Response.ok(await query.fetch());
}
Код модели My User: (я использую самоссылку)
class User extends ManagedObject<_User>
implements _User, ManagedAuthResourceOwner<_User> {
@Serialize(input: true, output: false)
String password;
@override
void willUpdate() {
updatedAt = DateTime.now().toUtc();
}
@override
void willInsert() {
updatedAt = DateTime.now().toUtc();
createdAt = DateTime.now().toUtc();
}
}
class _User extends ResourceOwnerTableDefinition {
@Column(unique: true, nullable: true)
String nickName;
String firstName;
String lastName;
/// this field defines the user type (active=helper, !active=help getter)
@Column(defaultValue: "'true'")
bool active;
DateTime birthday;
String street;
String houseNumber;
String zipCode;
String country;
String city;
double long;
double lat;
String placeId;
@Column(nullable: true)
String telephone;
@Column(nullable: true)
String mobile;
@Relate(#users)
SecurityRole securityRole;
EmailConfirmation emailConfirmation;
IdConfirmation idConfirmation;
ForgetPassword forgetPassword;
ManagedSet<HelpRequest> requests;
DateTime createdAt;
DateTime updatedAt;
}
Обратите внимание, что мой оператор SQL будет выглядеть следующим образом это если я не использую предикат:
final map = await query.context.persistentStore.execute(
"SELECT id, parent_id, user_id, helpTopic_id, description, street, "
"houseNumber, zipCode, country, city, long, lat, placeId, "
"contactName, contactPhone, active, rating, notes, status_id, "
"updatedAt, createdAt FROM request AS r"
"WHERE parent_id IS NULL "
"AND status_id = @status_id "
"AND CalculateDistance(r.lat, r.long, @lat, @long) < @radius",
substitutionValues: {
'radius': radius,
'lat': location['lat'],
'long': location['long'],
'status_id': statusID
});