我如何在数据脚本中进行左连接(或多或少)?
how can i do left join (more or less) in datascript?
所以基本上我有一个订单列表,一个订单供应商列表和一个用户列表
每个订单都有一个 属性, :order/subscribers,它是零个或多个订阅者的向量。
我想知道订购的订阅人数。
下面的查询只提供有 1 个或多个订阅者的订单,但也需要有 0 个订阅者的订单
基本上我明白了:
([4 "Provider1" "images/p1-logo.png" "orange" #inst "1970-01-01T00:00:00.000-00:00" 2]
[7 "Provider2" "images/p2-logo.png" "red" #inst "1970-01-01T00:00:00.001-00:00" 1])
并且想要得到这个:
([4 "Provider1" "images/p1-logo.png" "orange" #inst "1970-01-01T00:00:00.000-00:00" 2]
[7 "Provider2" "images/p2-logo.png" "red" #inst "1970-01-01T00:00:00.001-00:00" 1]
[8 "Provider3" "images/p3-logo.png" "green" #inst "1970-01-01T00:00:00.001-00:00" 0])
这是我正在使用的查询和架构。
不确定我是否也应该添加一些样本数据。
[:find ?ord ?name ?image ?color ?deadline (count ?subscribers)
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[?ord :order/subscribers ?subscribers]]
(def schema {:order/provider {:db/valueType :db.type/ref}
:order/subscribers {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}})
提前干杯和致谢:)
您需要使用函数来获取属性值。这里,get-else
获取属性值(在 :db.cardinality/many
的情况下是一个集合),然后使用第二个函数来获取计数。请注意,count
fn 作为附加输入传递。另请注意 :find
中的 count 是一个完全不同的野兽 - 它是数据记录引擎的聚合指令,但 count
我们传入的输入只是一个常规的 Clojure count
.
(d/q '[:find ?ord ?name ?image ?color ?deadline ?sc
:in $ ?count
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[(get-else $ ?ord :order/subscribers nil) ?subscribers]
[(?count ?subscribers) ?sc]]
db count)
或者,您可以只传入同时进行属性获取和计数的 fn:
(d/q '[:find ?ord ?name ?image ?color ?deadline ?sc
:in $ ?subscribers-count
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[(?subscribers-count $ ?ord) ?sc]]
db (fn [db ord] (count (:order/subscribers (d/entity db ord)))))
希望对您有所帮助!
所以基本上我有一个订单列表,一个订单供应商列表和一个用户列表 每个订单都有一个 属性, :order/subscribers,它是零个或多个订阅者的向量。 我想知道订购的订阅人数。
下面的查询只提供有 1 个或多个订阅者的订单,但也需要有 0 个订阅者的订单
基本上我明白了:
([4 "Provider1" "images/p1-logo.png" "orange" #inst "1970-01-01T00:00:00.000-00:00" 2]
[7 "Provider2" "images/p2-logo.png" "red" #inst "1970-01-01T00:00:00.001-00:00" 1])
并且想要得到这个:
([4 "Provider1" "images/p1-logo.png" "orange" #inst "1970-01-01T00:00:00.000-00:00" 2]
[7 "Provider2" "images/p2-logo.png" "red" #inst "1970-01-01T00:00:00.001-00:00" 1]
[8 "Provider3" "images/p3-logo.png" "green" #inst "1970-01-01T00:00:00.001-00:00" 0])
这是我正在使用的查询和架构。
不确定我是否也应该添加一些样本数据。
[:find ?ord ?name ?image ?color ?deadline (count ?subscribers)
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[?ord :order/subscribers ?subscribers]]
(def schema {:order/provider {:db/valueType :db.type/ref}
:order/subscribers {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}})
提前干杯和致谢:)
您需要使用函数来获取属性值。这里,get-else
获取属性值(在 :db.cardinality/many
的情况下是一个集合),然后使用第二个函数来获取计数。请注意,count
fn 作为附加输入传递。另请注意 :find
中的 count 是一个完全不同的野兽 - 它是数据记录引擎的聚合指令,但 count
我们传入的输入只是一个常规的 Clojure count
.
(d/q '[:find ?ord ?name ?image ?color ?deadline ?sc
:in $ ?count
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[(get-else $ ?ord :order/subscribers nil) ?subscribers]
[(?count ?subscribers) ?sc]]
db count)
或者,您可以只传入同时进行属性获取和计数的 fn:
(d/q '[:find ?ord ?name ?image ?color ?deadline ?sc
:in $ ?subscribers-count
:where [?ord :order/provider ?pid]
[?pid :provider/name ?name]
[?pid :provider/image-url ?image]
[?pid :provider/color ?color]
[?ord :order/deadline ?deadline]
[(?subscribers-count $ ?ord) ?sc]]
db (fn [db ord] (count (:order/subscribers (d/entity db ord)))))
希望对您有所帮助!