设置考虑以下DataScript数据库的电影和演员,数据从learndatalogtoday.org被盗:以下代码可以在JVM / Clojure REPL或ClojureScript REPL中执行,只要由于project.clj
包含[datascript "0.15.0"]
作为依赖项。
(ns user
(:require [datascript.core :as d]))
(def data
[["First Blood" ["Sylvester Stallone" "Brian Dennehy" "Richard Crenna"]]
["Terminator 2: Judgment Day" ["Linda Hamilton" "Arnold Schwarzenegger" "Edward Furlong" "Robert Patrick"]]
["The Terminator" ["Arnold Schwarzenegger" "Linda Hamilton" "Michael Biehn"]]
["Rambo III" ["Richard Crenna" "Sylvester Stallone" "Marc de Jonge"]]
["Predator 2" ["Gary Busey" "Danny Glover" "Ruben Blades"]]
["Lethal Weapon" ["Gary Busey" "Mel Gibson" "Danny Glover"]]
["Lethal Weapon 2" ["Mel Gibson" "Joe Pesci" "Danny Glover"]]
["Lethal Weapon 3" ["Joe Pesci" "Danny Glover" "Mel Gibson"]]
["Alien" ["Tom Skerritt" "Veronica Cartwright" "Sigourney Weaver"]]
["Aliens" ["Carrie Henn" "Sigourney Weaver" "Michael Biehn"]]
["Die Hard" ["Alan Rickman" "Bruce Willis" "Alexander Godunov"]]
["Rambo: First Blood Part II" ["Richard Crenna" "Sylvester Stallone" "Charles Napier"]]
["Commando" ["Arnold Schwarzenegger" "Alyssa Milano" "Rae Dawn Chong"]]
["Mad Max 2" ["Bruce Spence" "Mel Gibson" "Michael Preston"]]
["Mad Max" ["Joanne Samuel" "Steve Bisley" "Mel Gibson"]]
["RoboCop" ["Nancy Allen" "Peter Weller" "Ronny Cox"]]
["Braveheart" ["Sophie Marceau" "Mel Gibson"]]
["Mad Max Beyond Thunderdome" ["Mel Gibson" "Tina Turner"]]
["Predator" ["Carl Weathers" "Elpidia Carrillo" "Arnold Schwarzenegger"]]
["Terminator 3: Rise of the Machines" ["Nick Stahl" "Arnold Schwarzenegger" "Claire Danes"]]])
(def conn (d/create-conn {:film/cast {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}
:film/name {:db/unique :db.unique/identity
:db/cardinality :db.cardinality/one}
:actor/name {:db/unique :db.unique/identity
:db/cardinality :db.cardinality/one}}))
(def all-datoms (mapcat (fn [[film actors]]
(into [{:film/name film}]
(map #(hash-map :actor/name %) actors)))
data))
(def all-relations (mapv (fn [[film actors]]
{:db/id [:film/name film]
:film/cast (mapv #(vector :actor/name %) actors)}) data))
(d/transact! conn all-datoms)
(d/transact! conn all-relations)
描述简而言之,这个数据库中有两种实体 - 电影和演员(意图是不变的词) - 以及三种数据:
:film/name
(唯一字符串):film/cast
(多个参考):actor/name
(唯一字符串) 问题我想构建一个查询,询问:哪些电影有这些N
演员,和这些N
演员单独,出现了作为唯一的恒星,对于N> = 2?
例如,RoboCop主演南希艾伦,彼得韦勒,罗尼考克斯,但没有电影只出演了前两部分,艾伦和韦勒。因此,我希望以下查询生成空集:
(d/q '[:find ?film-name
:where
[?film :film/name ?film-name]
[?film :film/cast ?actor-1]
[?film :film/cast ?actor-2]
[?actor-1 :actor/name "Nancy Allen"]
[?actor-2 :actor/name "Peter Weller"]]
@conn)
; => #{["RoboCop"]}
然而,查询存在缺陷,因为我不知道如何表达任何比赛应该排除任何不是艾伦或韦勒的演员 - 我想找到只有艾伦和韦勒合作的电影任何其他演员,所以我想调整上面的查询来产生空集。如何调整此查询以强制执行此要求?
答案 0 :(得分:3)
因为DataScript没有否定(截至2016年5月),所以我不相信纯粹的“静态查询”可以做到这一点。数据记录。
我要走的路是:
这是一个基本实现
private void DocumentOpened(object sender)
{
Word._Document document = Globals.ThisAddIn.Application.ActiveDocument;
Office.DocumentProperties properties = document.BuiltInDocumentProperties;
if((properties["Author"].Value as string).Equals("MyMenuTool"))
{
//Show or activate the menu
}
}
答案 1 :(得分:0)
您可以一起使用谓词乐趣和d/entity
来按实体的:film/cast
字段过滤数据。在Datascript不支持否定(不运算符等)之前,这种方法看起来更直接。
查看Datascript here
的测试用例中的行(= a (:age (d/entity db e))
[{:db/id 1 :name "Ivan" :age 10}
{:db/id 2 :name "Ivan" :age 20}
{:db/id 3 :name "Oleg" :age 10}
{:db/id 4 :name "Oleg" :age 20}]
...
(let [pred (fn [db e a]
(= a (:age (d/entity db e))))]
(is (= (q/q '[:find ?e
:in $ ?pred
:where [?e :age ?a]
[(?pred $ ?e 10)]]
db pred)
#{[1] [3]})))))
在你的情况下,谓词正文可能看起来像这样
(clojure.set/subset? actors (:film/cast (d/entity db e))
关于性能,d/entity
调用很快,因为它是按索引查找。