考虑到数据体不支持分页,我想知道如何有效地支持查询,如:
以
:history/body
上的前30个实体为例,查找其:history/body
与某些正则表达式匹配的实体。
下面是我如何单独进行regex匹配:
{:find [?e]
:where [[?e :history/body ?body]
[(re-find #"foo.*bar$" ?body)]]}
意见:
(take ...)
,但这与匹配前30个实体不一样。take 30
然后用re-find
手动过滤,但是如果我有3000万个实体,那么将它们全部转移到take 30
似乎效率很低。另外:如果我想从我的3000万个实体中取出2000万并通过re-find
过滤它们,该怎么办?Datomic讨论了查询是如何在本地执行的,但是我尝试过对一组52913个实体(当然,它们完全是touch
编辑的)进行内存中的转换,这需要花费大约5秒。想象一下,在数百万或一千万人中,情况会有多糟。
发布于 2014-10-07 21:23:42
(这里只是集思广益)
首先,如果您曾经使用regexp,您可能需要考虑对:history/body的全文索引,以便您可以这样做:
[(fulltext $ :history/body "foo*bar") [[?e]]]
(注意:不能更改现有实体模式上的:db/fulltext true/false
)
排序是在查询之外必须做的事情。但是,根据您的数据,您可以将查询限制为单个“页面”,然后将谓词应用于这些实体。
例如,如果我们只是通过一个自动递增的:history
对:history/id
实体进行分页,那么我们就会事先知道“Page3”是:history/id
61到90。
[:find ?e
:in $ ?min-id ?max-id
:where
[?e :history/id ?id]
(<= ?min-id ?id ?max-id)
(fulltext $ :history/body "foo*bar") [[?e]]]
也许是这样的:
(defn get-filtered-history-page [page-n match]
(let [per-page 30
min-id (inc (* (dec page-n) per-page))
max-id (+ min-id per-page)]
(d/q '[:find ?e
:in $ ?min-id ?max-id ?match
:where
[?e :history/id ?id]
[(<= ?min-id ?id ?max-id)]
[(fulltext $ :history/body ?match) [[?e]]]]
(get-db) min-id max-id match)))
但是,当然,问题是约束分页集通常是基于事先不知道的排序,所以这并不是很有帮助。
https://stackoverflow.com/questions/26064582
复制相似问题