在 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 端点的人不是同一个人。