在 vapor4 中返回合理的数据
Returning reasonable data in vapor4
主要问题在func all
。当我的距离小于 100 米(不包括我自己)时,我想获得 Pers
模型。我知道我的 return 语句不能写在 for 循环中。但我实际上并不知道如何分配我的过滤器。
控制器:
import Foundation
import Vapor
import Fluent
import CoreLocation
final class UserLocationController{
func take (_ req: Request) throws -> HTTPStatus{
let userlocation = try req.content.decode(UserLocation.self);
let defalts = UserDefaults.standard
defalts.setValue(userlocation.latitude, forKey: "latitude")
defalts.setValue(userlocation.longitude, forKey: "longitude")
return HTTPStatus.ok
}
func all (_ req: Request) throws ->EventLoopFuture<[Pers]>{
let users = try req.content.decode([UserLocation].self)
let latitude = UserDefaults.standard.double(forKey: "latitude")
let longitude = UserDefaults.standard.double(forKey: "longitude")
let userlocation = CLLocation(latitude: latitude, longitude: longitude)
let newUsers = users.filter{ user in
let location = CLLocation(latitude: user.latitude, longitude: user.longitude)
return location.distance(from: userlocation) < 100
}
for value in newUsers{
let user = value.user
return Pers.query(on: req.db).filter(\.$user.$id == user).all()
}
}
}
UserLocation
型号:
import Foundation
import Vapor
import FluentPostgresDriver
struct UserLocation: Content{
var id:UUID?
var latitude: Double
var longitude: Double
var user: User.IDValue
}
Pers
型号:
import Foundation
import Fluent
import Vapor
import FluentPostgresDriver
final class Pers:Model,Content{
static let schema = "pers"
@ID(key: .id)
var id:UUID?
@Field(key: "姓名")
var name: String
@Field(key: "IG帳號")
var account: String
@Field(key: "頭像")
var picture: String
@Field(key: "年紀")
var age: String
@Field(key: "生日")
var birth: String
@Field(key: "居住城市")
var city: String
@Field(key: "興趣")
var hobby : String
@Parent(key: "user_id")
var user: User
init(){}
init(id:UUID?=nil, name:String, account:String, picture:String ,age:String, birth:String, city:String, hobby:String, userId:UUID){
self.id=id
self.name=name
self.account=account
self.picture=picture
self.age=age
self.birth=birth
self.city=city
self.hobby=hobby
self.$user.id=userId
}
}
简短的回答是您可以使用 subset query 从子集中获取所有用户,例如
return Pers.query(on: req.db).filter(\.$user.$id ~~ newUsers.compactMap { [=10=].id }).all()
但是您的代码存在许多严重的问题。对于初学者,如果您计划部署到 Linux,则不能使用 CoreLocation。其次,您在服务器而不是数据库上执行位置过滤器,因此如果您有很多用户,那么查询会很慢,因为您需要从数据库中获取每个用户。 PostGIS 查询会更有效率。
最后,您想要通过用户默认值实现什么?它们不应在服务器端使用 Swift。你拥有它的方式是,坐标将从最后访问 take
端点的人获取,即使访问 all
端点的人不是同一个人。
主要问题在func all
。当我的距离小于 100 米(不包括我自己)时,我想获得 Pers
模型。我知道我的 return 语句不能写在 for 循环中。但我实际上并不知道如何分配我的过滤器。
控制器:
import Foundation
import Vapor
import Fluent
import CoreLocation
final class UserLocationController{
func take (_ req: Request) throws -> HTTPStatus{
let userlocation = try req.content.decode(UserLocation.self);
let defalts = UserDefaults.standard
defalts.setValue(userlocation.latitude, forKey: "latitude")
defalts.setValue(userlocation.longitude, forKey: "longitude")
return HTTPStatus.ok
}
func all (_ req: Request) throws ->EventLoopFuture<[Pers]>{
let users = try req.content.decode([UserLocation].self)
let latitude = UserDefaults.standard.double(forKey: "latitude")
let longitude = UserDefaults.standard.double(forKey: "longitude")
let userlocation = CLLocation(latitude: latitude, longitude: longitude)
let newUsers = users.filter{ user in
let location = CLLocation(latitude: user.latitude, longitude: user.longitude)
return location.distance(from: userlocation) < 100
}
for value in newUsers{
let user = value.user
return Pers.query(on: req.db).filter(\.$user.$id == user).all()
}
}
}
UserLocation
型号:
import Foundation
import Vapor
import FluentPostgresDriver
struct UserLocation: Content{
var id:UUID?
var latitude: Double
var longitude: Double
var user: User.IDValue
}
Pers
型号:
import Foundation
import Fluent
import Vapor
import FluentPostgresDriver
final class Pers:Model,Content{
static let schema = "pers"
@ID(key: .id)
var id:UUID?
@Field(key: "姓名")
var name: String
@Field(key: "IG帳號")
var account: String
@Field(key: "頭像")
var picture: String
@Field(key: "年紀")
var age: String
@Field(key: "生日")
var birth: String
@Field(key: "居住城市")
var city: String
@Field(key: "興趣")
var hobby : String
@Parent(key: "user_id")
var user: User
init(){}
init(id:UUID?=nil, name:String, account:String, picture:String ,age:String, birth:String, city:String, hobby:String, userId:UUID){
self.id=id
self.name=name
self.account=account
self.picture=picture
self.age=age
self.birth=birth
self.city=city
self.hobby=hobby
self.$user.id=userId
}
}
简短的回答是您可以使用 subset query 从子集中获取所有用户,例如
return Pers.query(on: req.db).filter(\.$user.$id ~~ newUsers.compactMap { [=10=].id }).all()
但是您的代码存在许多严重的问题。对于初学者,如果您计划部署到 Linux,则不能使用 CoreLocation。其次,您在服务器而不是数据库上执行位置过滤器,因此如果您有很多用户,那么查询会很慢,因为您需要从数据库中获取每个用户。 PostGIS 查询会更有效率。
最后,您想要通过用户默认值实现什么?它们不应在服务器端使用 Swift。你拥有它的方式是,坐标将从最后访问 take
端点的人获取,即使访问 all
端点的人不是同一个人。