0

我正在使用 monger 并使用 find-maps 从我的 mongo nosql 数据库中获取一批。它返回一个数组,我计划将其用作函数调用链下游的数据存储参数(引用)。在这些未来的函数调用中,我将可以访问相应的 id。我希望将此 id 用作在我的数据存储中获取的查找,这样我就不必再打一个贩子电话了。数组形式的数据存储似乎不是通过 id 访问对象的最快方法......但我不确定。

如果我需要从这个数据存储数组派生一个对象,那么我需要使用这样的函数(必须在每个元素上记录(n))

(defn fetchObjFromArray [fetch_id inputarray]

    (reduce (fn [reduced_obj element_obj]

                (if (= fetch_id (get-in element_obj [:_id]))
                    element_obj ;; ignoring duplicates for conversation
                    reduced_obj 
                )    
            )
            {}
            inputarray
    )
)

相反,如果在我最初的 monger 调用之后,我使用如下函数创建一个 key/val 哈希对象:

(defn createReportFromObjArray [inputarray]

    (reduce (fn [returnobj elementobj]

                (let [_id (get-in elementobj [:_id])
                      keyword (keyword _id)]

                    (assoc returnobj keyword elementobj)
                ) ;; ignoring duplicates for conversation
            )
            {}
            inputarray)
)

那么也许我的后续调用可以改为使用 get-in 并且会更快,因为我将通过键获取?

我很困惑,因为:当我使用 get-in 时,它是否必须遍历 key/val has object 中的每个键,直到它找到键和 fetch_id 之间的匹配项:

(let [report (createReportFromObjArray inputarray)
      target_val (get-in report [(keyword fetch_id)])]

为什么 get-in 不必在每个键上记录(n)?也许它更快,因为它可以在找到第一个“匹配”时停止,其中 map/reducing 必须全程通过 log(n)?这比必须遍历数组中的每个元素并检查 id 是否与 fetch_id 匹配要快得多?

我非常感谢您能提供的帮助。

4

1 回答 1

3

在您的第二个代码示例中,您将在线性时间内构建一个 Clojure 哈希映射。通过get和推导它们具有 O(log32(N)) 的查找性能。

在第一个示例中,您扫描整个输入并返回与 ID 或空哈希映射匹配的最后一个元素,这可能是无意的。

_

我建议使用(group-by :_id)而不是第二个代码示例。我还建议使用(first (filter (comp #{fetch_id} :_id) inputarray))代替第一个示例。

避免通过转换为关键字keyword- Clojure 关键字通常应该在编译时知道。地图支持任意数据类型作为键。

于 2016-11-06T18:44:45.210 回答