当前位置: 首页 > 面试题库 >

由于Firebase查询中的大量元素而处理内存使用情况

常智勇
2023-03-14
问题内容

我正在编写将Firebase中的元素附加到数组以使用文本字段执行简单搜索的代码。

该方法的代码如下:

 var filteredEvents = [Event]()
var eventsArray = [Event]()
fileprivate func fetchEvents(){
    print("Fetching events....")
    //create a reference to the location in the database that you want to pull from and observe the value there
    let ref = Database.database().reference().child("events")
    // this will retur a snapshot with all the data at that location in the database and cast the results as a dictionary for later use
    ref.observe(.value, with: { (snapshot) in
        guard let dictionaries = snapshot.value as? [String: Any] else{
            return
        }
        //does the job of sorting dictionary elements by key and value
        //displaying the key and each corresponding value
        dictionaries.forEach({ (key,value) in
           // print(key, value)
            //creating an eventDictionary to store the results of previous call
            guard let eventDictionary = value as? [String: Any] else{
                return
            }
            //will cast each of the values as an Event based off my included struct
            //Make sure to create a model it is the only way to have the data in the format you want for easy access
             let events = Event(currentEventKey: key, dictionary:eventDictionary)
            // appends that to the dictionary to create the dictionary of events
            self.eventsArray.append(events)
        })
        // will sort the array elements based off the name
        self.eventsArray.sort(by: { (event1, event2) -> Bool in
            return event1.currentEventName.compare(event2.currentEventName) == .orderedAscending
        })
        // will again reload the data
        self.collectionView?.reloadData()

    }) { (err) in
        print("Failed to fetch events for search")
    }
}

我个人没有想到有可能发生很多事件的机会。我将无法将所有1000多个事件附加到字典中。那会刺痛我的记忆。无论如何,我可以让查询响应文本字段。也有人可以帮助我完成执行该操作但不会破坏我的记忆的查询行吗?

"events" : {
"CCDS" : {
  "attend:count" : 1,
  "event:date" : {
    "end:date" : "08/09/2017",
    "end:time" : "7:00 PM",
    "start:date" : "08/09/2017",
    "start:time" : "5:00 PM"
  },
  "event:description" : "Happy hour is more joyful in the summer thanks to Center City District Sips, which offers discounted drinks and appetizers every Wednesday evening.  Catch up with old friends and make a few new ones as Center City’s best bars and restaurants host the summer’s happiest hour every Wednesday from 5-7 p.m.  Enjoy $5 cocktails, $4 wine, $3 beers and half-price appetizers at dozens and dozens of bars and restaurants.",
  "event:imageURL" :someURL",
  "event:location" : {
    "event:city" : "Philadelphia",
    "event:state" : "PA",
    "event:street:address" : "660 Chestnut St",
    "event:zip" : 19106
  },
  "event:name" : "Center City District Sips"
},
"MIA" : {
  "attend:count" : 1,
  "event:date" : {
    "end:date" : "09/03/2017",
    "end:time" : "7:00 PM",
    "start:date" : "09/02/2017",
    "start:time" : "12:00 PM"
  },
  "event:description" : "Budweiser Made in America Festival is an annual music festival held in Philadelphia and formerly simultaneously held in Los Angeles.Sponsored by Anheuser–Busch and produced by Live Nation, the event features several stages that continuously host live music from a wide range of genres including hip hop, rock, pop, R&B, and EDM.",
  "event:imageURL" : "someURL",
  "event:location" : {
    "event:city" : "Philadelphia",
    "event:state" : "PA",
    "event:street:address" : "Ben Franklin Parkway",
    "event:zip" : 19130
  },
  "event:name" : "Made In America"
}
  },

例如,我想提取有关使用查询搜索的事件的所有信息。因此,如果我开始输入“美国制造”,它将从“事件”标签中提取有关该事件的所有相关信息

这是我目前拥有的

fileprivate func fetchEvents(searchString: String){
    print("Fetching events....")
    //create a reference to the location in the database that you want to pull from and observe the value there
    let ref = Database.database().reference().child("events")
    // this will retur a snapshot with all the data at that location in the database and cast the results as a dictionary for later use
  let query = ref.queryOrdered(byChild: "event:name").queryEqual(toValue: searchString)
    print(query)
    query.observeSingleEvent(of: .value, with: { (snapshot) in
        guard let dictionary = snapshot.value as? [String: Any] else{
            print(snapshot.value)
            return
        }
        print(snapshot.value)
    }) { (err) in
        print("Failed to fetch event data", err)
    }

}

返回此

(/events { ep = Made In America; i = "event:name"; sp = Made In America; })


问题答案:

看来问题是

"How can I query for a value contained in a child node?"

给出与原始结构相似的结构

"events" : {
  "CCDS" : {
    "attend:count" : 1,
    "event:imageURL" :"someURL",
    "event:name" : "Center City District Sips"
  "MIA" : {
    "attend:count" : 1,
    "event:imageURL" : "someURL",
    "event:name" : "Made In America"

Firebase查询将返回您想要的节点。

如果用户键入 “美国制造” 并点击搜索按钮,则查询将返回快照中的该节点。

let searchString = "Made In America"
let ref = self.ref.child("events")
let query = ref.queryOrdered(byChild: "event:name").queryEqualTo(searchString)
query.observeSingleEvent(of: .value, with: { (snapshot) in
    for child in snapshot.children {
        let snap = child as! DataSnapshot
        let eventDict = snap.value as! [String: Any]
        let attendCount = eventDict["attend:count"] as! String
        let url = eventDict["event:imageURL"} as! String
    }
})

如果您想进行部分字符串匹配,则用户可以只输入几个字符,例如 Made 代码类似,但是您需要让firebase返回所有以Made开头的匹配项…

查询看起来像这样

let startString = "Made"
let endString = "Made" + "\\uf8ff"
let query = ref.queryOrdered(byChild: "event:name")
                        .queryStarting(atValue: startString)
                        .queryEnding(atValue: endString")

“ \ uf8ff”是Unicode中很高代码级别的字符-因为它包含所有前面的字符。

但是,“即时”查询会创建无响应或反应迟缓的UI,因此不建议这样做。

一种替代方法是创建一个单独的节点,该节点包含的信息要少得多,并包含用户要搜索的元素以及对事件节点的引用。

所以包含所有数据的主节点看起来像这样

"events" : {
  "-uyuh8s8j8jsdas" : {
    "event": "CCDS"
    "attend:count" : 1,
    "event:imageURL" : "someURL",
  "-y88jsijsijjids" : {
    "event": "MIA"
    "attend:count" : 1,
    "event:imageURL" : "someURL",

一个“较小”的节点看起来像这样

   events_for_searching
       -uyuh8s8j8jsdas
         event:name: "Center City District Sips"
       -y88jsijsijjids
         event:name: "Made In America"

这样,您可以将来自events_for_searching的所有节点加载到一个数组中(然后根据用户类型过滤该数组),这将使UI非常敏感,并且当用户选择名称时,您可以使用该节点中的键作为参考,以便通过observeSingleEvent函数从事件节点加载数据。

编辑

为了回应评论,我想在代码中添加更多细节。

这是我的结构

  "events" : {
    "event_0" : {
      "event:name" : "An Event"
    },
    "event_1" : {
      "event:name" : "Made In America"
    }
  },

以及用于查询事件的代码:名称:美国制造

let searchString = "Made In America"
let ref = self.ref.child("events")
let query = ref.queryOrdered(byChild: "event:name").queryEqual(toValue: searchString)

query.observeSingleEvent(of: .value, with: { (snapshot) in
    guard let dictionary = snapshot.value as? [String: Any] else{
        print(snapshot.value)
        return
    }
    print(snapshot.value)
}) { (err) in
    print("Failed to fetch event data", err)
}

和输出

Optional({
    "event_1" =     {
        "event:name" = "Made In America";
    };
})


 类似资料:
  • 问题内容: 我正在尝试处理重量级元素(图像)的收集。集合的大小在8000-50000个条目之间变化。但是由于某种原因,在处理了1800-1900个条目之后,我的程序因java.lang.OutOfMemoryError:Java堆空间而掉线。 以我的理解,每次调用session.getTransaction()。commit()程序都应该释放堆内存,但是看起来它永远不会发生。我做错了什么?这是代码

  • 问题内容: 当redis达到“最大内存”条件时,它将允许客户端进行读取,但不能进行写入。 当然,这将导致致命错误……有什么方法可以使Rails处理缓存的读或写错误,因此,如果缓存发生问题(可用性,读取,写入等),它将继续以如果缓存设置为“关闭”? 问题答案: 您可以告诉redis在内存已满时要遵守的不同行为。 默认是 也许最好的选择是’volatile-ttl’,并确保所有缓存都包括:expire

  • 问题内容: 我写了一个程序,可以总结如下: 实际代码(尤其是)要复杂得多。仅使用将其当作参数的这些值(意味着它不引用) 基本上,它将巨大的数据集加载到内存中并进行处理。输出的写操作委托给一个子进程(它实际上写到多个文件中,这需要很多时间)。因此,每次处理一个数据项时,它都会通过res_queue发送到子流程,然后该子流程根据需要将结果写入文件中。 子流程不需要访问,读取或修改以任何方式加载的数据。

  • 查询#shadow-root内部的元素是发生了奇怪的问题 和 分别是#shadow-root内外的两个元素通过F12在元素页面右键复制JS路径获得,当我在元素页面点击#shadow-root外部的元素代码时,可以查询#shadow-root外的元素,查询内部元素为null,当我在元素页面点击#shadow-root内部的元素代码时,可以查询#shadow-root内的元素,查询外部元素为null,

  • 最近开发了一个数据流消费者,它从PubSub订阅中读取数据,并将分组在同一窗口中的所有对象的组合输出到拼花文件。 当我在没有巨大负载的情况下进行测试时,一切似乎都很好。 然而,在执行了一些繁重的测试后,我可以看到,从发送到PubSub队列的1.000.000个事件中,只有1000个事件成功到达Parket! 根据不同阶段的多个墙时间,在应用窗口之前解析事件的墙时间似乎持续58分钟。写入拼花文件的最

  • 我需要通过prometheus查询获得kubernetes吊舱中的CPU和内存使用情况。有人能帮忙吗?