我有一个Mongodb集合,其中包含具有一定尺寸的产品,我想按一定顺序对其进行排序。
在SQL中,您可以进行import Foundation
protocol ExampleService {
typealias PersonCompletion = (PagedResult<Person>) -> Void
func persons(page: Int, resultsPerPage: Int, completion: @escaping PersonCompletion)
}
class ExampleWebService: ExampleService {
func persons(page: Int, resultsPerPage: Int, completion: @escaping (PagedResult<Person>) -> Void) {
let url = URL(string: "https://example.com/api/?action=persons_detailed&limit=\(resultsPerPage)")!
let task = session.dataTask(with: url) { (data, response, error) in
guard let data = data else {
return
}
do {
try validate(response)
let persons: [Person] = try parse(data)
let personPage = PagedResult(pageNumber: page, results: persons)
completion(personPage)
print(data)
}
catch {
print("Error: \(error)")
}
}
task.resume()
}
}
size import UIKit
class PersonListViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var personPages: [PagedResult<Person>] = [] {
didSet {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
loadPersons()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
guard let selectedIndexPath = collectionView.indexPathsForSelectedItems?.first else {
return
}
collectionView.deselectItem(at: selectedIndexPath, animated: animated)
}
var service = ExampleWebService()
private func loadPersons(page: Int = 0, resultsPerPage: Int = 10) {
service.persons(page: page, resultsPerPage: resultsPerPage) { (personPage) in
guard !self.loadedPersonPageNumbers.contains(page) else { return }
self.personPages.append(personPage)
self.updateLastIndexPath(personPage)
}
}
private(set) var lastIndexPath: IndexPath?
private func updateLastIndexPath(_ personPage: PagedResult<Person>) {
if personPage.results.isEmpty {
lastIndexPath = nil
}
else {
lastIndexPath = calculateLastIndexPath()
}
}
private func calculateLastIndexPath() -> IndexPath? {
guard let lastPage = personPages.last else { return nil }
let section = lastPage.pageNumber
let row = lastPage.results.count - 1
return IndexPath(row: row, section: section)
}
fileprivate var loadedPersonPageNumbers: [Int] {
return personPages.map { $0.pageNumber }
}
func person(at indexPath: IndexPath) -> Person? {
guard indexPath.section < personPages.count else {
return nil
}
guard indexPath.row < personPages[indexPath.section].results.count else {
return nil
}
let page = personPages[indexPath.section]
return page.results[indexPath.row]
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let personViewController = segue.destination as? PersonViewController,
let selectedIndexPath = collectionView.indexPathsForSelectedItems?.first else {
return
}
personViewController.person = person(at: selectedIndexPath)
}
@IBAction func exitToPersonsView(segue: UIStoryboardSegue) {
}
}
extension PersonListViewController: UICollectionViewDelegate {
fileprivate var nextPageIndex: Int {
guard let lastPage = personPages.last else {
return 0
}
return lastPage.pageNumber.advanced(by: 1)
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if indexPath == lastIndexPath {
loadPersons(page: nextPageIndex)
}
}
}
的操作,但是我完全不知道如何使用mongodb实现这种操作。
答案 0 :(得分:2)
不幸的是sort(for queries)/orderBy(for aggregations)
遵循以下语法:
<field1>: <sort order>;
因此,您不能复制与SQL中相同的行为。 您的解决方案可能是在过滤器中传递orderBy / sort,然后再次查询这些结果。
另一种解决方案是使用聚合,但是您必须指定最终结果中要包含产品中的哪些字段:
db.products.aggregate( [ { $group : { _id : "$size", products: { $push: "$name" } } } ] )
响应如下所示:
{“ _id”:“ L”,“产品”:[]} {“ _id”:“ M”,“产品”:[ “ a”,“ b”]}
另一个聚合示例,该示例首先过滤产品,然后将它们分组:
db.products.aggregate([
{ $match: { size: { $in: ["M", "L"] } } },
{ $group: { _id: "$size", products: { $push: {name: "$name", size:"$size"} } } }
]);
// { "_id" : "M", "products" : [ { "name" : "a2", "size" : "M" } ] }
// { "_id" : "L", "products" : [ { "name" : "a1", "size" : "L" }, { "name" : "a3", "size" : "L" } ] }