最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - How can I prioritize posts based on categories that match a user's array of interests, showing those posts first,

programmeradmin0浏览0评论
 static func fetchFeedPostsWithPagination(lastDocument: DocumentSnapshot?, limit: Int) async throws -> (posts: [Post], lastDocument: DocumentSnapshot?) {
        
        let uid = Auth.auth().currentUser?.uid
        let currentUser = try await UserService.fetchUser(withUid: uid ?? "")
        let userCategories = currentUser.categories?.keys.map { $0 } ?? []  // Convert keys to an array
        
        var query: Query = postsCollection
        
        if !userCategories.isEmpty {
            query = query.whereField("category", in: userCategories)
        }
        
        query = query.order(by: "timestamp", descending: true)
        
        query = query.limit(to: limit)
        
        if let lastDocument = lastDocument {
            query = query.start(afterDocument: lastDocument)
        }
        
        let snapshot = try await query.getDocuments()
        var posts = try snapshot.documentspactMap { try $0.data(as: Post.self) }
        
        for i in 0 ..< posts.count {
            let ownerUid = posts[i].ownerUid
            let postUser = try await UserService.fetchUser(withUid: ownerUid)
            posts[i].user = postUser
        }
        
        let lastDoc = snapshot.documents.last
        return (posts, lastDoc)
    }

I’ve tried using .order to prioritize posts based on categories in a user’s array of interests, but I can’t figure out how to implement it correctly. Additionally, I want to maintain pagination since there will be a large number of posts, and I don’t want to fetch them all at once. How can I achieve this?

 static func fetchFeedPostsWithPagination(lastDocument: DocumentSnapshot?, limit: Int) async throws -> (posts: [Post], lastDocument: DocumentSnapshot?) {
        
        let uid = Auth.auth().currentUser?.uid
        let currentUser = try await UserService.fetchUser(withUid: uid ?? "")
        let userCategories = currentUser.categories?.keys.map { $0 } ?? []  // Convert keys to an array
        
        var query: Query = postsCollection
        
        if !userCategories.isEmpty {
            query = query.whereField("category", in: userCategories)
        }
        
        query = query.order(by: "timestamp", descending: true)
        
        query = query.limit(to: limit)
        
        if let lastDocument = lastDocument {
            query = query.start(afterDocument: lastDocument)
        }
        
        let snapshot = try await query.getDocuments()
        var posts = try snapshot.documentspactMap { try $0.data(as: Post.self) }
        
        for i in 0 ..< posts.count {
            let ownerUid = posts[i].ownerUid
            let postUser = try await UserService.fetchUser(withUid: ownerUid)
            posts[i].user = postUser
        }
        
        let lastDoc = snapshot.documents.last
        return (posts, lastDoc)
    }

I’ve tried using .order to prioritize posts based on categories in a user’s array of interests, but I can’t figure out how to implement it correctly. Additionally, I want to maintain pagination since there will be a large number of posts, and I don’t want to fetch them all at once. How can I achieve this?

Share Improve this question edited Feb 1 at 23:27 Frank van Puffelen 600k85 gold badges889 silver badges859 bronze badges Recognized by Mobile Development Collective and Google Cloud Collective asked Feb 1 at 21:36 CobraCodesCobraCodes 391 silver badge5 bronze badges 4
  • 2 This is not possible with a single query; you are either filtering the results with in or you are not. Your result set can't include results that don't match the query. What is the desired behaviour? If there are, say, 1000 posts, and the oldest post matches one of the user's interests and the newest doesn't, should the oldest post be shown before the newest post? I think you would need to keep fetching documents until the query returns nothing, and then start a new query using not in instead of in – Paulw11 Commented Feb 1 at 21:42
  • There is a CoreMl from apple somewhere that does this. Probably with on device training samoles – lorem ipsum Commented Feb 1 at 21:44
  • @Paulw11 you have actually helped me out so much! I got it to work! thank you!! – CobraCodes Commented Feb 1 at 22:16
  • @Paulw11 Great answer! Feel like posting it below? – Frank van Puffelen Commented Feb 1 at 23:30
Add a comment  | 

1 Answer 1

Reset to default 1

You can't use a single query to get both the posts that the user is interested in and those that don't match their interests; the two query criteria are opposite.

Since you want to show the "interesting" posts first, followed by the remainders, you can use two queries.

  • First, request posts with query.whereField("category", in: userCategories)
  • Once you have retrieved all of these documents, then you can issue a new query query.whereField("category", notIn: userCategories) - You can be sure that none of these documents were in the initial query.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论