ååã®å¾©ç¿
ååã®ã³ã¡ã³ããããKeywordãUtil.read(String)ã§åå¾ã§ãããã¨ãããã£ãã®ã§ãæå¾ã®ãµã³ãã«ã³ã¼ããä¿®æ£ãã¦ã¿ã¾ãã
@Test void queryPullApiWithRelation() { Database db = connection.db() def results = Peer.query('[:find (pull ?c [*]) :where[?c :community/name]]', db) int rows = 0 results.each {PersistentVector vec -> if (rows ++ < 2) { // çµæåã®1é ç®ç®(ã¨ã³ãã£ãã£ãã®ãã®)ãåå¾ PersistentArrayMap map = vec.get(0) // ã¨ã³ãã£ãã£ãã:community/neighborhoodãåå¾ PersistentArrayMap nbh = map.get(keyword(':community/neighborhood')) // :community/neighborhoodãã:db/idãåå¾ãã¦ã¨ã³ãã£ãã£ã«å¤æ EntityMap neighborhood = db.entity(nbh.get(keyword(':db/id'))) // :neighborhoodã¨ã³ãã£ãã£ãã:neighborhood/nameãåå¾ def name = neighborhood.get(':neighborhood/name') LOG.debug "[${test.methodName}] neighborhood: [class: [${name.getClass()}], value: ${name}]" } } }
å®è¡çµæã¯æ¬¡ã®ã¨ããã«ãªã
neighborhood: [class: [class java.lang.String], value: Capitol Hill] neighborhood: [class: [class java.lang.String], value: Admiral (West Seattle)]
è¦äºã«ã¯ã¨ãªã¼ããé¢é£ããé ç®ãåã£ã¦ãããã¨ãã§ãã¾ãã
ãã ãã覧ã®ã¨ããé¢åãªæä½ã§ããäºå®ã¯å¦ãã¾ããã
ã¢ããªãã¥ã¼ãã®å¤ãåå¾ãã
ããã¾ã§ã®ã¯ã¨ãªã¼ã¯æ¬¡ã®ãããªå½¢ã«ãªã£ã¦ãã¾ãã
[:find ?c :where[?c :community/name]]
ãã ãã¢ããªã±ã¼ã·ã§ã³ã¯ãã¼ã¿ã®å¤æãããããã®ã§ã¯ãªãããã¼ã¿ãã®ãã®ãåå¾ãããã®ã§ããdatomicã§ã¯:findã«å¤æ°ã追å ãã¦:whereã§å¤ãææããæ¬¡ã®ãããªã¯ã¨ãªã¼ãæä¾ããã¦ãã¾ãã
[:find ?c ?n :where[?c :community/name ?n]]
ã§ã¯ããã®å¼ãå®è¡ãã¦ã¿ã¾ãããã
@Test void queryWithAttributesValue() { Database db = connection.db() def results = Peer.query('[:find ?c ?n :where[?c :community/name ?n]]', db) def vec = results[0] assert vec.size() == 2 [[index: 0, expectedType: Long], [index: 1, expectedType: String]].each { assert vec[it.index].getClass() == it.expectedType def e = db.entity(vec[it.index]) LOG.debug "[${test.methodName}] [idx[$it.index]: [class: [${vec[it.index].getClass()}], value: [${vec[it.index]}], entity: [$e]]" } }
ãã®ã¯ã¨ãªã¼ããè¿ã£ã¦ããçµæã?cã¯ã¨ã³ãã£ãã£ã®idã§ãã?nã¯:community/nameã®å¤ã§ãããã¨ãæ³å®ããã¾ããã§ã¯å®è¡ãã¦ã¿ã¾ãããã
[idx[0]: [class: [class java.lang.Long], value: [17592186045461], entity: [{:db/id 17592186045461}]]
[idx[1]: [class: [class java.lang.String], value: [Ballard Avenue], entity: [null]]
ã¿ãã¨assertã«å¤±æãããã¨ãªãéãã¾ãããã¾ããå®éã«:community/nameã®å¤ãåå¾ã§ãã¦ããããã§ãã
Longã®idãªãããããªãã®ã§ãæååã ããã
ã¨ããã§æ¯åãã¯ã¨ãªã¼ã®çµæã«ã¨ã³ãã£ãã£ã®idãå
¥ã£ã¦ããã®ãé¢åãªè©±ã ããçµæã¯Stringã®ãªã¹ãã®å½¢ã§ã»ããããã§ããããã§ãdatomicã§ã¯æ¬¡ã®ãããªã¯ã¨ãªã¼ãæ¸ããã¨ãã§ãã¾ãã
[:find [?n ...] :where[_ :community/name ?n]]
:findã®é¨åã«ã¯[?n ...]ã§çµæããªã¹ãã§åå¾ããããã«æç¤ºãã¾ãã:whereã§ã¯_ã¨ããè¦æ £ããªãè¨å·ãåºã¦ãã¾ããããã¡ãã¡ã¨ã³ãã£ãã£ãä½ããã®å¤æ°ã«ææããå¿ è¦ããªãã¨ãã«ç¨ãããã¨ãã§ãã¾ããããã¦ãæçµçã«:community/nameã夿°?nã«ææãã¾ããScalaãªã©ã§ãããç¨ãã¦ãã¾ãã(æ£èªã¿
ã§ã¯ãå®è¡ãã¦ã¿ã¾ãããã
@Test void queryAttributeList() { Database db = connection.db() def results = Peer.query('[:find [?n ...] :where[_ :community/name ?n]]', db) assert results.size() == 132 results.eachWithIndex {value, index -> assert value.class == String if(index < 2) { LOG.debug "[${test.methodName}] :community/name[${value}]" } } }
å®è¡çµæ
:community/name[KOMO Communities - Ballard] :community/name[Ballard Blog]
æååã®ãªã¹ãã§åå¾ã§ããããã§ãã
ä¸ã¤ã®ã¨ã³ãã£ãã£ã®ä¸ã®è¤æ°ã®è¦ç´ ãåå¾ãã
DBã«ã¢ã¯ã»ã¹ãããªããå¤ãï¼ã¤ãã¤ã§ã¯ãªãããã£ã¤ãåã£ã¦ãããã§ããdatomicã§ããã¡ããã§ãã¾ããSQLããè¥å¹²ã¯ã¨ãªã¼ãé¢åãªãã¨ã«ãªã£ã¦ãã¾ãããããã»ã©é£ãããã®ã§ã¯ãªãã§ãã
[:find ?n ?u :where [?c :community/name ?n][?c :community/url ?u]]
:find ?n ?uã§è¤æ°ã®å¤ãåå¾ãã¾ã:whereã«æ¸¡ãå¼ã®æåã§ã¯?cã«:communityã¨ã³ãã£ãã£ãææãã¦ããªããã¤:community/nameã?nã«ææãã¾ã:whereã«æ¸¡ãå¼ã®ï¼ã¤ç®ã§ã¯ææããã?cã®ã¨ã³ãã£ãã£ãã:community/urlãåãåºãã¦?uã«ææãã¾ã
ããã«ãããä¸ã¤ã®ã¨ã³ãã£ãã£ããè¤æ°ã®è¦ç´ ãåå¾ã§ãã¾ãã
@Test void queryMultipleAttributes() { Database db = connection.db() def results = Peer.query('[:find ?n ?u :where [?c :community/name ?n] [?c :community/url ?u]]', db) assert results.size() == 150 def vec = results[0] assert vec.size() == 2 [0, 1].each { assert vec[it].class == String } LOG.debug "[${test.methodName}] :community/name[${vec[0]}], :community/url[${vec[1]}]" }
å®è¡çµæã¯æ¬¡ã®ã¨ãã
:community/name[Broadview Community Council], :community/url[http://groups.google.com/group/broadview-community-council]
ã·ã³ãã«
ã¨ããã§ãã¯ã¨ãªã¼ã§?uã¨ã?nã¨ã使ã£ã¦ã¾ããã©ãããã¯?nameã¨ã?-urlã¨ãurlã¨ã使ããã®ã§ããããï¼å®éã«è©¦ãã¦ã¿ã¾ãã
@Test void ã¯ã¨ãªã®å¤æ°ã§ä½¿ããå½¢å¼() { Database db = connection.db() def queryBase = [ [index: 0, variable: '?name', attr: ':community/name'], [index: 1, variable: '?-url', attr: ':community/url'], [index: 2, variable: 'cat', attr: ':community/category'] ] [2,3].each {attrs -> def qb = queryBase.findAll {it.index < attrs} def vars = qb.collect{it.variable}.join(' ') def condition = qb.collect {"[?c ${it.attr} ${it.variable}]"}.join('') def query = "[:find ${vars} :where ${condition}]" as String LOG.debug(query) def results = Peer.query(query, db) assert results.size() == 150 } }
å®è¡çµæ
[:find ?name ?-url :where [?c :community/name ?name][?c :community/url ?-url]] [:find ?name ?-url cat :where [?c :community/name ?name][?c :community/url ?-url][?c :community/category cat]] java.lang.IllegalArgumentException: Argument cat in :find is not a variable
ä¾å¤ãæãããã¾ãããæ°ããcatã¯å¤æ°ã§ã¯ãªããã¨ã䏿¹ã§?-urlã¯å¤æ°ã¨ãã¦ä½¿ããã¨ãã§ããããã§ãã
å®éã®æãã¯ã¨ãªã¼ã«é¢ããããã¥ã¡ã³ããè¦ãã¨ã夿°ã®å®ç¾©ã¯æ¬¡ã®ããã«ãªã£ã¦ãã¾ãã
variable = symbol starting with "?"
(夿°ã¯?ã§å§ã¾ãã·ã³ãã«)
ã¾ããã·ã³ãã«ã¨ã¯edn(extensible data notation)ã§ã®ç¨èªã§ã次ã®ããã«å®ç¾©ããã¦ãã¾ãã
Symbols begin with a non-numeric character and can contain alphanumeric characters and
. * + ! - _ ? $ % & = < >. If-,+or.are the first character, the second character (if any) must be non-numeric. Additionally,: #are allowed as constituent characters in symbols other than as the first character.
ç°¡åã«ã¾ã¨ããã¨æ¬¡ã®ã¨ãã
- æåã®æåã«ä½¿ããªãæåã¯æ°åã
:ã# -ã+ã.ã§å§ã¾ãå ´åã¯æ¬¡ã®æåã¯æ°å以å¤ã®æå
ããã¡ãã£ã¨å®ç¾©ãããã®ã§ãããããã¯ä¸è¨ã®ednã®ããã¥ã¡ã³ããèªãã»ããæ©ãã§ãã
ã«ã¼ãã£ããªãã£ãManyã®ãã¤
ãæååã ããããã¨ããè¦åºãã®é¨åã®:community/nameã ããåãåºãã¯ã¨ãªã¼ã¯çµæã®æ°ã132ã§ãããã:communityãåã£ã¦ããã¨çµæã150ããã¾ãããã®éãã¯ä½ã§ããããï¼ããã§ãååãæ²è¼ãããã¥ã¼ããªã¢ã«ã«æ¸ããã¦ããã¨ã³ãã£ãã£ã®å®ç¾©ãåæ²ãã¾ãã
| attribute | type | cardinality |
|---|---|---|
| :community/name | String | One |
| :community/url | String | One |
| :community/neighborhood | Reference | One |
| :community/category | String | Many |
| :community/orgtype | Reference | One |
| :community/type | Reference | One |
:community/categoryã®ã«ã¼ãã£ããªãã£ãmanyã«ãªã£ã¦ãã¾ãããããéè¤ãã¦ããåã§ãã
ããã§
æ¡ä»¶ãã¤ãã¦çµãè¾¼ãã¯ã¨ãªã¼
[:find ?community ?category :where[?community :community/name "belltown"][?community :community/category ?category]]
ãçºè¡ãã¦ã¿ã¾ãã
@Test void ã«ã¼ãã£ããªãã£ãManyãªãã¤() { Database db = connection.db() def results = Peer.query('[:find ?community ?category :where[?community :community/name "belltown"][?community :community/category ?category]]', db) assert results.size() == 2 results.each {vec -> LOG.debug "[${test.methodName}] category[${vec[1]}]" } }
å®è¡çµæ
category[news] category[events]
ãã¼ã¿çµè¾¼
æ¡ä»¶ã§ã®ãã¼ã¿ã®çµãè¾¼ã¿ã¯æ¬¡ã®ãããªå½¢ã§è¡ãã¾ãã
:whereã«ç¶ããvectorã§çµè¾¼ãã¨ã³ãã£ãã£ããåå¾ããè¦ç´ ã®é¸æãé¢é£ããã¨ã³ãã£ãã£ã®æå®ãè¡ã[?entity :entity/attribute ?attribute]ã®å½¢ã§?entityã«ææããã¦ããã¨ã³ãã£ãã£/è¦ç´ ããæå®ãã:entity/attributeã?attributeã«ææãã[?entity :entity/attribute "value"]ã®å½¢ã§?entityã«ææããã¦ããã¨ã³ãã£ãã£/è¦ç´ ã®æå®ãã:entity/attributeã«å¯¾ãã¦æå®ãã"value"ã§ãããã³ã°ãã
ä¾:
[:find
?name ?url
:where
[?c :community/name "Broadview Community Council"]
[?c :community/url ?url]
[?c :community/name ?name]]
?cã:community/nameã®ã¨ã³ãã£ãã£ã«ææ:community/nameã"Broadview Community Council"ã§ãããã³ã°?cã«ææãããã¨ã³ãã£ãã£(:community)ã®è¦ç´:community/urlã?urlã«ææ?cã«ææãããã¨ã³ãã£ãã£(:community)ã®è¦ç´:community/nameã?nameã«ææ- çµæã¨ãã¦
?nameã?urlãè¿ã
ã§ã¯ãå®éã«è©¦ãã¦ã¿ã¾ãããã
@Test void queryWithCondition() { Database db = connection.db() def results = Peer.query($/ [:find ?name ?url :where [?c :community/name "Broadview Community Council"] [?c :community/url ?url] [?c :community/name ?name]]/$ as String, db) results.each {vec -> LOG.debug "[${test.methodName}] find community with name[Broadview Community Council] -> name[${vec[0]}], url[${vec[1]}]" } }
å®è¡çµæ
find community with name[Broadview Community Council] -> name[Broadview Community Council], url[http://groups.google.com/group/broadview-community-council] find community with name[Broadview Community Council] -> name[Broadview Community Council], url[http://www.broadviewseattle.org/]
æå®ãã:community/nameãæã£ãã¨ã³ãã£ãã£ãåå¾ã§ãã¦ãããã¨ããããã¾ãã
è¤æ°ã®ã¨ã³ãã£ãã£ã«ã¾ããã£ãæ¡ä»¶ã§ã®çµè¾¼
:whereã«æå®ããVectorã®è¨è¿°ã®ä»æ¹ã«ãã£ã¦ãã¨ã³ãã£ãã£ã®çµåãå¯è½ã§ãã
ä¾
:where
[?c :community/neighborhood ?n]
[?n :neighborhood/district ?d]
[?d :district/region :region/ne]
?cã®ã¨ã³ãã£ãã£/è¦ç´ ãã:community/neighborhoodã?nã«ææ?nã«ææãããã¨ã³ãã£ãã£:neighborhoodãã:neighborhood/districtã?dã«ææ?dã«ææãããã¨ã³ãã£ãã£:districtãã:district/regionã:region/neã§ãããã³ã°
ãã®ããã«è¤æ°ã®ã¨ã³ãã£ãã£ãçµåãã¤ã¤ãæ¡ä»¶ã§ã®çµãè¾¼ã¿ãå¯è½ã«ãªãã¾ãã
@Test void queryAcrossReferences() { Database db = connection.db() List results = Peer.query($/ [:find [?c_name ...] :where [?c :community/name ?c_name] [?c :community/neighborhood ?n] [?n :neighborhood/district ?d] [?d :district/region :region/ne]]/$ as String, db) assert results.size() == 9 results.eachWithIndex{name, index -> if (index < 2 || index == 8) { LOG.debug "[${test.methodName}] :community/name[${name}]" } } }
å®è¡çµæã¯æ¬¡ã®ã¨ããã«ãªãã¾ãã
:community/name[Maple Leaf Community Council] :community/name[Hawthorne Hills Community Website] :community/name[Magnuson Environmental Stewardship Alliance]
çµè¾¼ããããã¼ã¿ã®æ°ã¯9ä»¶ã§æåã¨2çªç®ãããã¦æå¾ã®è¦ç´ ã表示ãã¦ããã®ã§3ä»¶ã ã表示ããã¦ãã¾ãããã®ããã«è¤æ°ã®ã¨ã³ãã£ãã£ã«ã¾ããã£ãã¯ã¨ãªã¼ã®å®è¡ãå¯è½ã§ãã
ãããå¿ç¨ããã°ãè¤æ°ã®ã¨ã³ãã£ãã£ã§æ¡ä»¶ãæå®ãã¤ã¤ãè¤æ°ã®ã¨ã³ãã£ãã£ããè¦ç´ ã®å¤ãåå¾ãããã¨ãå¯è½ã§ãã
@Test void queryAcrossReferencesRetrievingCommunityNameAndRegionName() { Database db = connection.db() def results = Peer.query($/ [:find ?cname ?nname ?rname :where [?c :community/name "Broadview Community Council"] [?c :community/name ?cname] [?c :community/neighborhood ?n] [?n :neighborhood/name ?nname] [?n :neighborhood/district ?d] [?d :district/region ?r] [?r :db/ident ?rname]]/$ as String, db) results.each {PersistentVector vec -> LOG.debug "[${test.methodName}] communityName: [${vec[0]}], neighborhoodName: [${vec[1]}], regionName: [${vec[2]}]" } }
ãã®ãµã³ãã«ã³ã¼ãã§ã¯:community/nameã"Broadview Community Council"ã§ãããã³ã°ãã¤ã¤ã:community/nameã:neighborhood/nameã:district/regionã®å¤ãåå¾ãã¦ãã¾ãããªãã:district/regionã®å¤ã«ã¤ãã¦ã¯enumåãªã®ã§:db/identã¨ããã¨ã³ãã£ãã£/è¦ç´ ã®å¤ã?rnameã«ææãã¦ãã¾ããå®è¡çµæã¯æ¬¡ã®ã¨ããã«ãªãã¾ãã
communityName: [Broadview Community Council], neighborhoodName: [Broadview], regionName: [:region/sw]
æå®ããã¨ããã®ãã¼ã¿ãåå¾ã§ãã¦ãã¾ããã
åæ¥ã§æéããã£ããããçµæ§é·ãã®ã¨ã³ããªã¼ã«ãªãã¾ããã
次åã¯ãã©ã¡ã¼ã¿ã¼ãæå®ããã¯ã¨ãªã¼ãããããã¨æãã¾ãã
ããã