Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 对分页集执行筛选的高效Datomic查询_Clojure_Datomic_Datalog - Fatal编程技术网

Clojure 对分页集执行筛选的高效Datomic查询

Clojure 对分页集执行筛选的高效Datomic查询,clojure,datomic,datalog,Clojure,Datomic,Datalog,鉴于Datomic,我想知道如何有效地支持以下查询: 以:history/body上的前30个实体为例,查找其 :history/body与某些正则表达式匹配 下面是我单独进行正则表达式匹配的方法: {:find[?e] :where[?e:历史/正文?正文] [(重新查找#“foo.*bar$”?body)]] 意见: 然后我可以从这些实体中(取…),但这与匹配前30个实体不同 我可以获取所有实体,获取30个,然后使用重新查找手动筛选,但如果我有3000万个实体,那么将所有实体仅获取30个似

鉴于Datomic,我想知道如何有效地支持以下查询:

:history/body
上的前30个实体为例,查找其
:history/body
与某些正则表达式匹配

下面是我单独进行正则表达式匹配的方法:

{:find[?e]
:where[?e:历史/正文?正文]
[(重新查找#“foo.*bar$”?body)]]
意见:

  • 然后我可以从这些实体中
    (取…
    ),但这与匹配前30个实体不同
  • 我可以获取所有实体,
    获取30个
    ,然后使用
    重新查找
    手动筛选,但如果我有3000万个实体,那么将所有实体仅获取30个似乎效率极低。另外:如果我想从3000万个实体中拿出2000万个,并通过
    重新查找
    对其进行过滤,该怎么办
  • Datomic文档讨论了如何在本地执行查询,但我尝试了在52913个实体上进行内存转换(当然,它们完全是
    touch
    ed),需要大约5秒钟。想象一下,在数百万人或千万人中,情况会有多糟。

    (这里只是头脑风暴)

    首先,如果您使用过ReGEXP,您可能需要考虑一个FultLeXT索引:历史/正文,这样您就可以做到:

    [(fulltext $ :history/body "foo*bar") [[?e]]]
    
    (注意:不能在现有实体架构上更改
    :db/fulltext true/false

    排序是您必须在查询之外执行的操作。但是,根据您的数据,您可以将查询约束到单个“页面”,然后将谓词仅应用于这些实体

    例如,如果我们只是通过自动递增的
    :history/id
    :history
    实体进行分页,那么我们会事先知道“第3页”是
    :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]]]
    
    [:查找?e
    :单位为$?最小id?最大id
    :在哪里
    [?e:历史记录/id?id]
    
    (谢谢。有机会的时候我会解决这个问题,看起来是个好的开始。
    (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)))