Search Datomic-选择某些属性中最高的实体
假设我有一个电影列表,我可以通过以下方式获得它们:Search Datomic-选择某些属性中最高的实体,search,max,datomic,Search,Max,Datomic,假设我有一个电影列表,我可以通过以下方式获得它们: [:find ?year ?title ?rating :where [?Movie :movie/year ?year ] [?Movie :movie/year ?title ] [?Movie :movie/year ?rating]] 我如何进一步限制这一点,以获得最高评级的电影?我觉得我想要像 [:find ?year ?title ?rating :where [?Movie :movie/year ?year ]
[:find ?year ?title ?rating
:where
[?Movie :movie/year ?year ]
[?Movie :movie/year ?title ]
[?Movie :movie/year ?rating]]
我如何进一步限制这一点,以获得最高评级的电影?我觉得我想要像
[:find ?year ?title ?rating
:where
[?Movie :movie/year ?year ]
[?Movie :movie/year ?title ]
[?Movie :movie/year ?rating]
[(= ?rating (max ?rating) ]]
但是很明显,这不会实现我想要的=提示?用Datomic中的两个查询来实现这类功能是可以的。让对等方在本地缓存数据库意味着在一个查询中完成同样多任务的压力稍微减轻了一点
[:find (max ?year) .
:where [?m :movie/year ?year]]
其次是:
[:find ?maxyear ?title ?rating
:in $ ?maxyear
:where [?m :movie/year ?maxyear]
[?m :movie/title ?title]
[?m :movie/rating ?rating]]
没关系。Clojure中的链接查询可能如下所示:
(let [db (d/db conn)]
(->>
(d/q '[:find (max ?year) .
:where [?m :movie/year ?year]]
db)
(d/q '[:find ?maxyear ?title ?rating
:in $ ?maxyear
:where [?m :movie/year ?maxyear]
[?m :movie/title ?title]
[?m :movie/rating ?rating]]
db)))
注意,在let绑定中,我们只从连接中获取一次db值。可以使用集合返回函数来获得您提到的具有正确约束的结果,但这可能不是您所期望的结果-如获得最新披头士版本的示例所示:
(d/q '[:find (max ?tuple)
:where [?e :artist/name "The Beatles"]
[?a :release/artists ?e]
[?a :release/year ?y]
[?a :release/name ?n]
[(vector ?y ?n) ?tuple]]
(d/db conn))
这依赖于第一个元素的隐式排序,但它对多个最大值的行为如何?这将返回:
[[[2011 "Love"]]]
但是如果没有max,我们可以看到max拉的不是唯一的:
[[2011 "1"]] [[2011 "Love"]]
如果您知道预期数量,则可以设置,例如:
:find (max 2 ?tuple)
但这正带我们走上一条最好避免的道路。在大多数情况下,选择简单、更健壮的组合查询是有意义的。在Datomic中使用两个查询可以完成这类操作。让对等方在本地缓存数据库意味着在一个查询中完成同样多任务的压力稍微减轻了一点
[:find (max ?year) .
:where [?m :movie/year ?year]]
其次是:
[:find ?maxyear ?title ?rating
:in $ ?maxyear
:where [?m :movie/year ?maxyear]
[?m :movie/title ?title]
[?m :movie/rating ?rating]]
没关系。Clojure中的链接查询可能如下所示:
(let [db (d/db conn)]
(->>
(d/q '[:find (max ?year) .
:where [?m :movie/year ?year]]
db)
(d/q '[:find ?maxyear ?title ?rating
:in $ ?maxyear
:where [?m :movie/year ?maxyear]
[?m :movie/title ?title]
[?m :movie/rating ?rating]]
db)))
注意,在let绑定中,我们只从连接中获取一次db值。可以使用集合返回函数来获得您提到的具有正确约束的结果,但这可能不是您所期望的结果-如获得最新披头士版本的示例所示:
(d/q '[:find (max ?tuple)
:where [?e :artist/name "The Beatles"]
[?a :release/artists ?e]
[?a :release/year ?y]
[?a :release/name ?n]
[(vector ?y ?n) ?tuple]]
(d/db conn))
这依赖于第一个元素的隐式排序,但它对多个最大值的行为如何?这将返回:
[[[2011 "Love"]]]
但是如果没有max,我们可以看到max拉的不是唯一的:
[[2011 "1"]] [[2011 "Love"]]
如果您知道预期数量,则可以设置,例如:
:find (max 2 ?tuple)
但这正带我们走上一条最好避免的道路。在大多数情况下,选择简单、更健壮的组合查询是有意义的