在函数中要写什么以便根据条件进行排序?

huangapple go评论73阅读模式
英文:

What to write in the function so that the sorting is by condition?

问题

我正在使用Firebase编写一个SwiftUI应用程序。文档现在按发布日期排序。需要确保Firebase数据库中包含非空upPostPlusDay数组的文档显示在首位。以下是代码:

用于将数据写入Post数据库的模型:

import SwiftUI
import FirebaseFirestoreSwift

struct Post: Identifiable, Codable, Equatable, Hashable {
    @DocumentID var id: String?
    var text: String
    var postHead: String
    var postAddress: String
    var imageURL: URL?
    var imageReferenceID: String = ""
    var publishedDate: Date = Date()
    var likedIDs: [String] = []
    var dislikedIDs: [String] = []
    var plusFavorites: [String] = []
    var upPostPlusDay: [Int] = []
    var userName: String
    var userUID: String
    var userProfileURL: URL
    var userBioLink: String
    
    enum CodingKeys: CodingKey {
        case id
        case text
        case postHead
        case postAddress
        case imageURL
        case imageReferenceID
        case publishedDate
        case likedIDs
        case dislikedIDs
        case plusFavorites
        case upPostPlusDay
        case userName
        case userUID
        case userProfileURL
        case userBioLink
    }
}

向用户输出的代码:

import SwiftUI
import Firebase

struct ReusablePostViewContentView: View {
    var basedOnUID: Bool = false
    var uid: String = ""
    @Binding var posts: [Post]
    @State private var isFetching: Bool = true
    @State private var paginationDoc: QueryDocumentSnapshot?
    var body: some View {
        ScrollView (.vertical, showsIndicators: false) {
            LazyVStack {
                if isFetching {
                    ProgressView()
                        .padding(.top, 30)
                } else {
                    if posts.isEmpty {
                        Text("No posts")
                            .font(.caption)
                            .foregroundColor(.gray)
                            .padding(.top, 30)
                    } else {
                        Posts()
                    }
                }
            }
            .padding(15)
        }
        .refreshable {
            guard !basedOnUID else {return}
            isFetching = true
            posts = []
            paginationDoc = nil
            await fetchPosts()
        }
        .task {
            guard posts.isEmpty else {return}
            await fetchPosts()
        }
    }

    @ViewBuilder
    func Posts() -> some View {
        ForEach (posts) { post in
            PostCardViewContentView(postDog: post) { updatedPost in
                if let index = posts.firstIndex(where: { post in
                    post.id == updatedPost.id
                }) {
                    posts[index].likedIDs = updatedPost.likedIDs
                    posts[index].dislikedIDs = updatedPost.dislikedIDs
                }
            } onDelete: {
                withAnimation(.easeInOut(duration: 0.25)) {
                    posts.removeAll {post.id == $0.id}
                }
            }
            .onAppear {
                if post.id == posts.last?.id && paginationDoc != nil {
                    Task {await fetchPosts()}
                    // print("fetch new posts")
                }
            }
            
            Divider()
                .padding(.horizontal, -15)
        }
    }
    
    func fetchPosts() async {
        do {
            var query: Query!
            if let paginationDoc {
                query = Firestore.firestore().collection("Posts")
                    .order(by: "publishedDate", descending: true)
                    .start(afterDocument: paginationDoc)
                    .limit(to: 5)
            } else {
                query = Firestore.firestore().collection("Posts")
                    .order(by: "publishedDate", descending: true)
                    .limit(to: 5)
            }
            
            if basedOnUID {
                query = query.whereField("userUID", isEqualTo: uid)
            }
            
            let docs = try await query.getDocuments()
            let fetchedPosts = docs.documents.compactMap { doc -> Post? in
                try? doc.data(as: Post.self)
            }
            await MainActor.run(body: {
                posts.append(contentsOf: fetchedPosts)
                paginationDoc = docs.documents.last
                isFetching = false
            })
        } catch {
            print(error.localizedDescription)
        }
    }
}

希望这有所帮助。如果您有任何问题,请随时提问。

英文:

I am writing a swiftui application using firebase. Documents are now sorted by publication date. It is necessary that documents that contain a non-empty upPostPlusDay array in the Firebase database are shown in the first place. Here is the code.
Model for writing data to the Post database:

import SwiftUI
import FirebaseFirestoreSwift
struct Post: Identifiable, Codable, Equatable, Hashable {
@DocumentID var id: String?
var text: String
var postHead: String
var postAddress: String
var imageURL: URL?
var imageReferenceID: String = ""
var publishedDate: Date = Date()
var likedIDs: [String] = []
var dislikedIDs: [String] = []
var plusFavorites: [String] = []
var upPostPlusDay: [Int] = []
var userName: String
var userUID: String
var userProfileURL: URL
var userBioLink: String
enum CodingKeys: CodingKey {
case id
case text
case postHead
case postAddress
case imageURL
case imageReferenceID
case publishedDate
case likedIDs
case dislikedIDs
case plusFavorites
case upPostPlusDay
case userName
case userUID
case userProfileURL
case userBioLink
}
}

Output code to user:

import SwiftUI
import Firebase
struct ReusablePostViewContentView: View {
var basedOnUID: Bool = false
var uid: String = ""
@Binding var posts: [Post]
@State private var isFetching: Bool = true
@State private var paginationDoc: QueryDocumentSnapshot?
var body: some View {
ScrollView (.vertical, showsIndicators: false) {
LazyVStack {
if isFetching {
ProgressView()
.padding(.top, 30)
} else {
if posts.isEmpty {
Text("No posts")
.font(.caption)
.foregroundColor(.gray)
.padding(.top, 30)
} else {
Posts()
}
}
}
.padding(15)
}
.refreshable {
guard !basedOnUID else {return}
isFetching = true
posts = []
paginationDoc = nil
await fetchPosts()
}
.task {
guard posts.isEmpty else {return}
await fetchPosts()
}
}
@ViewBuilder
func Posts() -> some View {
ForEach (posts) { post in
PostCardViewContentView(postDog: post) { updatedPost in
if let index = posts.firstIndex(where: { post in
post.id == updatedPost.id
}) {
posts[index].likedIDs = updatedPost.likedIDs
posts[index].dislikedIDs = updatedPost.dislikedIDs
}
} onDelete: {
withAnimation(.easeInOut(duration: 0.25)) {
posts.removeAll {post.id == $0.id}
}
}
.onAppear {
if post.id == posts.last?.id && paginationDoc != nil {
Task {await fetchPosts()}
// print("fetch new posts")
}
}
Divider()
.padding(.horizontal, -15)
}
}
func fetchPosts() async {
do {
var query: Query!
if let paginationDoc {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.start(afterDocument: paginationDoc)
.limit(to: 5)
} else {
query = Firestore.firestore().collection("Posts")
.order(by: "publishedDate", descending: true)
.limit(to: 5)
}
if basedOnUID {
query = query.whereField("userUID", isEqualTo: uid)
}
let docs = try await query.getDocuments()
let fetchedPosts = docs.documents.compactMap { doc -> Post? in
try? doc.data(as: Post.self)
}
await MainActor.run(body: {
posts.append(contentsOf: fetchedPosts)
paginationDoc = docs.documents.last
isFetching = false
})
} catch {
print(error.localizedDescription)
}
}
}

Help me please.

答案1

得分: 0

需要在Firebase数据库中显示包含非空upPostPlusDay数组的文档排在第一位。没有可以添加到Firestore查询的子句,可以将具有特定非空数组的文档排在前面,同时获取所有其他文档。

解决方案是(通常在使用NoSQL数据库时)更改/扩展数据模型以支持该用例。

例如,如果您为每个文档添加一个字段upPostPlusDayValueCount,并在该字段中保持实时计数,您可以按降序upPostPlusDayValueCount排序,以获取具有非空upPostPlusDay数组的文档在结果开头的文档。

英文:

> It is necessary that documents that contain a non-empty upPostPlusDay array in the Firebase database are shown in the first place

There is no clause that you can add to a Firestore query to get documents with a specific non-empty array first, while also getting all other documents.


The solution is (as usual when working with NoSQL databases) to change/expand your data model to allow the use-case.

For example, if you add a field upPostPlusDayValueCount to each document, and keep an up-to-date count in that field, you can sort on descending upPostPlusDayValueCount to get the documents with a non-empty upPostPlusDay array at the start of the results.

huangapple
  • 本文由 发表于 2023年5月29日 14:55:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355228.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定