LOC-6: Small indexes for works and instances, person etc
[mp-sparql-moved-to-github.git] / bibframe / triplestore.xml
1 <?xml version="1.0"?>
2
3 <filters  xmlns="http://indexdata.com/metaproxy">
4     <filter type="sparql">
5
6         <!-- Which sparql server to use, our demo, or your local installation -->
7         <!--defaults uri="http://bibframe.indexdata.com/sparql/"/-->
8         <defaults uri="http://localhost:8890/sparql/"/>
9
10         <!-- "thing" database that will be included all real databases -->
11         <db path="thing">  <!-- no schema, so it is not directly searchable -->
12             <prefix>rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns</prefix>
13             <prefix>bf: http://bibframe.org/vocab/</prefix>
14             <form>SELECT DISTINCT ?thing </form>
15
16             <!-- Common indexes -->
17
18             <!-- bf.uri is a simple way to get to a thing -->
19             <index type="bf.uri">
20                 ?thing  rdf:type ?any FILTER( ?thing  = %u )
21             </index>
22
23             <!-- bf.type is a simple way to search for types -->
24             <!-- for example, a bf.Work can also be bf:Text or bf:Audio -->
25             <index type="bf.type">
26                 ?thing  a %t
27             </index>
28
29             <!-- The BF-L present format is the same for everything -->
30             <!-- Each db is supposed to provide a dedicated BF-V present format -->
31             <present type="BF-L">
32                 CONSTRUCT {
33                     %u ?rel ?subj
34                 }
35                 WHERE {
36                     %u ?rel ?subj .
37                 }
38             </present>
39
40         </db>
41
42         <!-- "smallindex" db that will be included in work and instance -->
43         <!-- It provides the small indexes like bf.person, bf.place, etc -->
44         <!-- These match a person, etc, no matter what the relation to that -->
45         <!-- is, as long as there is a direct link -->
46         <db path="smallindex">
47             <index type="bf.person">
48                 ?thing ?rel ?person .
49                 ?person a bf:Person .
50                 ?person bf:label %v FILTER(contains(%v, %s))
51             </index>
52             <index type="bf.topic">
53                 ?thing ?rel ?topic .
54                 ?topic a bf:Topic .
55                 ?topic bf:label %v FILTER(contains(%v, %s))
56             </index>
57             <index type="bf.place">
58                 ?thing ?rel ?place .
59                 ?place a bf:Place .
60                 ?place bf:label %v FILTER(contains(%v, %s))
61             </index>
62             <index type="bf.agent">
63                 ?thing ?rel ?person .
64                 ?person a bf:Agent .
65                 ?person bf:label %v FILTER(contains(%v, %s))
66             </index>
67             <index type="bf.meeting">
68                 ?thing ?rel ?meeting .
69                 ?meeting a bf:Meeting .
70                 ?meeting bf:label %v FILTER(contains(%v, %s))
71             </index>
72             <index type="bf.organization">
73                 ?thing ?rel ?organization .
74                 ?organization a bf:Organization .
75                 ?organization bf:label %v FILTER(contains(%v, %s))
76             </index>
77             <index type="bf.event">
78                 ?thing ?rel ?event .
79                 ?event a bf:Event .
80                 ?event bf:label %v FILTER(contains(%v, %s))
81             </index>
82         </db>
83
84         <!-- work database -->
85
86         <db path="work" schema="sparql-results" include="thing smallindex">
87
88             <!-- The search clause just finds ?things, present is done below -->
89             <criteria>?thing a bf:Work</criteria>
90
91             <!-- Title indexes -->
92             <!-- These are messy, there are so many ways to get to a title -->
93
94             <!-- Main title. Looks logical, but in practice we have not seen -->
95             <!-- many of these -->
96             <index type="bf.title">
97                     ?thing bf:title %v FILTER(contains(%v, %s))
98             </index>
99
100             <!-- worktitle.titleValue seems to be the most common way to -->
101             <!-- store the title of a work -->
102             <index type="bf.worktitle">
103                 ?thing bf:workTitle ?wt .
104                 ?wt bf:titleValue %v FILTER(contains(%v, %s))
105             </index>
106
107             <!-- Combining the two above, since users are not likely -->
108             <!-- to know how a given title has been indexed -->
109             <!-- TODO is "maintitle" a good name for this? I made it up myself -->
110             <index type="bf.maintitle">
111                 {
112                     ?thing bf:workTitle ?wt .
113                     ?wt bf:titleValue %v FILTER(contains(%v, %s))
114                 } UNION {
115                     ?thing bf:title %v FILTER(contains(%v, %s))
116                 }
117             </index>
118
119             <!-- the worktitle can also contain a subtitle and a parttitle -->
120             <index type="bf.subtitle">?thing bf:workTitle ?wt .
121                 ?wt bf:subtitle %v FILTER(contains(%v, %s))
122             </index>
123
124             <index type="bf.parttitle">
125                 ?thing bf:workTitle ?wt .
126                 ?wt bf:partTitle %v FILTER(contains(%v, %s))
127             </index>
128
129             <!-- work.titlevariation - this could also have sub- and partTitles -->
130             <index type="bf.titlevariation">
131                 ?thing bf:titleVariation ?tv .
132                 ?tv bf:titleValue %v FILTER(contains(%v, %s))
133             </index>
134
135             <!-- Instance titles -->
136             <index type="bf.instancetitle">
137                 ?inst bf:instanceOf ?thing .
138                 ?inst bf:instanceTitle ?it .
139                 ?it bf:titleValue %v FILTER(contains(%v, %s))
140             </index>
141
142             <!-- Combined title index. There are so many ways titles can be expresses
143             in Bibframe, this seems to cover most of what we have seen -->
144             <index type="bf.anytitle">
145                 {
146                     ?thing bf:title %v FILTER(contains(%v, %s))
147                 } UNION { <!-- any kind of link -->
148                     ?thing ?titlerel ?ti . <!-- mostly workTitle, but others too -->
149                     ?ti a bf:Title <!-- to something that is a title -->
150                     {
151                         ?ti bf:titleValue %v FILTER(contains(%v, %s))
152                     } UNION {
153                         ?ti bf:partTitle %v FILTER(contains(%v, %s))
154                     } UNION {
155                         ?ti bf:subtitle %v FILTER(contains(%v, %s))
156                     }
157                 } UNION {
158                     ?inst bf:instanceOf ?thing .
159                     ?inst bf:instanceTitle ?it .
160                     ?it bf:titleValue %v FILTER(contains(%v, %s))
161                 } UNION {
162                 }
163             </index>
164
165             <!-- Author indexes. Much simpler than titles. -->
166             <index type="bf.creator">
167                 ?thing bf:creator ?c .
168                 ?c bf:label %v FILTER(contains(%v, %s))
169             </index>
170
171             <index type="bf.contributor">
172                 ?thing bf:contributor ?c .
173                 ?c bf:label %v FILTER(contains(%v, %s))
174             </index>
175
176             <index type="bf.anyauthor"> <!-- TODO - Is this a good name? -->
177                 {
178                     ?thing bf:creator ?c .
179                     ?c bf:label %v FILTER(contains(%v, %s))
180                 } UNION {
181                     ?thing bf:contributor ?c .
182                     ?c bf:label %v FILTER(contains(%v, %s))
183                 }
184             </index>
185
186             <!-- Subjects -->
187             <!-- Note that these refer to anything with a bf:subject relation -->
188             <!-- The actual item is likely to be something like topic person etc -->
189             <index type="bf.subject">
190                 ?thing bf:subject ?subject .
191                 ?subject bf:label %v FILTER(contains(%v, %s))
192             </index>
193
194             <!-- contentCategory can be searched with complete URIs like -->
195             <!-- http://id.loc.gov/vocabulary/contentTypes/txt -->
196             <index type="bf.contentcategory">
197                 ?thing bf:contentCategory %u
198             </index>
199
200             <!-- Present formats -->
201             <!-- BF-L comes from the "thing" template -->
202             <!-- BF-V expands all links, even to instances but not other works -->
203             <present type="BF-V">
204                 CONSTRUCT {
205                     %u ?wrel1 ?wobj1 .
206                     ?wobj1 ?wrel2 ?wobj2 .
207                     ?wobj2 ?wrel3 ?wobj3 .
208                     ?inst ?irel1 ?iobj1 .
209                     ?iobj1 ?irel2 ?iobj2 .
210                     ?iobj2 ?irel3 ?iobj3
211                 }
212                 WHERE {
213                     %u a bf:Work .
214                     %u ?wrel1 ?wobj1 .
215
216                     OPTIONAL {
217                         ?wobj1 ?wrel2 ?wobj2
218                             MINUS { ?wobj1 a bf:Work }
219                             MINUS { ?wobj1 a bf:Instance }
220                         OPTIONAL {
221                             ?wobj2 ?wrel3 ?wobj3
222                                 MINUS { ?wobj2 a bf:Work }
223                                 MINUS { ?wobj2 a bf:Instance }
224                         }
225                     }
226                     <!-- Link to the instance(s) -->
227                     OPTIONAL {
228                         ?inst bf:instanceOf %u .
229                         ?inst ?irel1 ?iobj1
230                         OPTIONAL {
231                             ?iobj1 ?irel2 ?iobj2
232                                 MINUS { ?iobj1 a bf:Work }
233                                 MINUS { ?iobj1 a bf:Instance }
234                             OPTIONAL {
235                                 ?iobj2 ?irel3 ?iobj3
236                                     MINUS { ?iobj2 a bf:Work }
237                                     MINUS { ?iobj2 a bf:Instance }
238                             }
239                         }
240                     }
241                 }
242             </present>
243         </db>
244
245         <!-- Instance database -->
246
247         <db path="instance" schema="sparql-results" include="thing smallindex">
248             <criteria>?thing a bf:Instance</criteria>
249
250             <!-- Title indexes -->
251             <!-- These are messy, there are so many ways to get to a title -->
252
253             <!-- Main title. Looks logical. Many instances seem to have a title -->
254             <index type="bf.title">
255                 ?thing bf:title %v FILTER(contains(%v, %s))
256             </index>
257
258             <!-- instancetitle is also pretty common -->
259             <index type="bf.instancetitle">
260                 ?thing bf:instanceTitle ?it .
261                 ?it bf:titleValue %v FILTER(contains(%v, %s))
262             </index>
263
264             <index type="bf.titlestatement">
265                 ?thing bf:titleStatement %v FILTER(contains(%v, %s))
266             </index>
267
268             <!-- Combining the two above, since users are not likely to know how
269             a given title has been indexed -->
270             <index type="bf.maintitle">
271                 {
272                     ?thing bf:instanceTitle ?it .
273                     ?it bf:titleValue %v FILTER(contains(%v, %s))
274                 } UNION {
275                     ?thing bf:title %v FILTER(contains(%v, %s))
276                 }
277             </index>
278
279
280             <!-- the instancetitle can also contain a subtitle and a parttitle -->
281             <index type="bf.subtitle">
282                 ?thing bf:instanceTitle ?it .
283                 ?it bf:subtitle %v FILTER(contains(%v, %s))
284             </index>
285
286             <index type="bf.parttitle">
287                 ?thing bf:instanceTitle ?it .
288                 ?it bf:partTitle %v FILTER(contains(%v, %s))
289             </index>
290             <!-- We could also go to the works, and get those titles... -->
291
292             <!-- Combining any kind of title into one index -->
293             <index type="bf.anytitle">
294                 {
295                     ?thing bf:title %v FILTER(contains(%v, %s))
296                 } UNION {
297                     ?thing bf:titleStatement %v FILTER(contains(%v, %s))
298                 } UNION {
299                     ?thing ?titlerel ?it . <!-- any kind of link -->
300                     ?it a bf:Title <!-- to something that is a title -->
301                     {
302                         ?it bf:titleValue %v FILTER(contains(%v, %s))
303                     } UNION {
304                         ?it bf:partTitle %v FILTER(contains(%v, %s))
305                     } UNION {
306                         ?it bf:subtitle %v FILTER(contains(%v, %s))
307                     }
308                 }
309             </index>
310
311             <!-- Author indexes. Many instances don't have any, works do -->
312             <index type="bf.creator">
313                 ?thing bf:creator ?c .
314                 ?c bf:label %v FILTER(contains(%v, %s))
315             </index>
316
317             <index type="bf.workcreator">
318                 ?thing bf:instanceOf ?work .
319                 ?work bf:creator ?c .
320                 ?c bf:label %v FILTER(contains(%v, %s))
321             </index>
322
323             <index type="bf.workcontributor">
324                 ?thing bf:instanceOf ?work .
325                 ?work bf:contributor ?c .
326                 ?c bf:label %v FILTER(contains(%v, %s))
327             </index>
328
329             <index type="bf.contributor">
330                 ?thing bf:contributor ?c .
331                 ?c bf:label %v FILTER(contains(%v, %s))
332             </index>
333
334             <index type="bf.anyauthor">
335                 {
336                     ?thing bf:creator ?c .
337                     ?c bf:label %v FILTER(contains(%v, %s))
338                 } UNION {
339                     ?thing bf:contributor ?c .
340                     ?c bf:label %v FILTER(contains(%v, %s))
341                 } UNION {
342                     ?thing bf:instanceOf ?work .
343                     ?work bf:creator ?c .
344                     ?c bf:label %v FILTER(contains(%v, %s))
345                 } UNION {
346                     ?thing bf:instanceOf ?work .
347                     ?work bf:contributor ?c .
348                     ?c bf:label %v FILTER(contains(%v, %s))
349                 }
350             </index>
351
352             <!-- isbn index. The Instance may contain a isbn10 or isbn13. -->
353             <!-- These can be literal values like -->
354             <!--   http://isbn.example.org/1906833214 which we need to search -->
355             <!-- by our usual substring match. Or they can be links to Identivfiers -->
356             <!-- which will have a proper identifierValue on which we can do -->
357             <!-- an exact match.  -->
358             <index type="bf.isbn">
359                 {
360                     ?thing bf:isbn10  %v
361                         FILTER(isUri(%v) &amp;&amp; contains(str(%v), %s))
362                 } UNION {
363                     ?thing bf:isbn13  %v
364                         FILTER(isUri(%v) &amp;&amp; contains(str(%v), %s))
365                 } UNION {
366                     {
367                         ?thing bf:isbn10 ?isbn
368                     } UNION {
369                         ?thing bf:isbn13 ?isbn
370                     }
371                     ?isbn a bf:Identifier  .
372                     ?isbn bf:identifierValue  %v FILTER( %v = %s )
373                 }
374             </index>
375
376
377             <!-- Present formats. BF-L comes from "thing" -->
378             <!-- Full instance, with the related work too -->
379             <present type="BF-V">
380                 CONSTRUCT {
381                     %u ?irel1 ?iobj1 .
382                     ?iobj1 ?irel2 ?iobj2 .
383                     ?iobj2 ?irel3 ?iobj3 .
384                     ?work ?wrel1 ?wobj1 .
385                     ?wobj1 ?wrel2 ?wobj2 .
386                     ?wobj2 ?wrel3 ?wobj3
387                 }
388                 WHERE {
389                     %u a bf:Instance .
390                     %u ?irel1 ?iobj1 .
391                     OPTIONAL {
392                         ?iobj1 ?irel2 ?iobj2
393                             MINUS { ?iobj2 a bf:Work }
394                             MINUS { ?iobj2 a bf:Instance } .
395                         OPTIONAL {
396                             ?iobj2 ?irel3 ?iobj3
397                                 MINUS { ?iobj3 a bf:Work }
398                                 MINUS { ?iobj3 a bf:Instance }
399                         }
400                     }
401                     OPTIONAL { <!-- Work -->
402                         %u bf:instanceOf ?work .
403                         ?work ?wrel1 ?wobj1 .
404                         OPTIONAL {
405                             ?wobj1 ?wrel2 ?wobj2
406                                 MINUS { ?wobj1 a bf:Work }
407                                 MINUS { ?wobj1 a bf:Instance } .
408                             OPTIONAL {
409                                 ?wobj2 ?wrel3 ?wobj3
410                                     MINUS { ?wobj2 a bf:Work }
411                                     MINUS { ?wobj2 a bf:Instance }
412                             }
413                         }
414                     }
415                 }
416             </present>
417
418         </db>
419
420         <!-- Small databases -->
421
422         <!-- "small" contains all the things common to all small databases -->
423         <!-- It is only to be used as an include, it is not searchable, since -->
424         <!-- it has no schema atribute -->
425         <!-- It is divided into "smallbody", and a "small" that includes -->
426         <!-- the general indexes, so that title searches can include the body, -->
427         <!-- but have different "any" indexes -->
428
429         <db path="smallbody" include="thing">
430             <present type="BF-V">
431                 <!-- I don't think we need more than one level -->
432                 <!--for these simple databases -->
433                 CONSTRUCT {
434                     %u ?rel ?obj .
435                     ?obj ?rel1 ?obj1 .
436                 }
437                 WHERE {
438                     %u ?rel ?obj .
439                     OPTIONAL { ?obj ?rel1 ?obj1 }
440                 }
441             </present>
442         </db>
443
444         <!-- The combined "small" database defaults -->
445         <db path="small" include="smallbody">
446             <index type="any">
447                 ?thing bf:label %v FILTER(contains(%v, %s))
448             </index>
449             <index type="1016">
450                 ?thing bf:label %v FILTER(contains(%v, %s))
451             </index>
452         </db>
453
454         <!-- Various "small" databases, leaning heavily on the defaults above -->
455         <db path="place" schema="sparql-results" include="small" >
456             <criteria>?thing a bf:Place</criteria>
457             <index type="bf.place">
458                 ?thing bf:label %v FILTER(contains(%v, %s))
459             </index>
460         </db>
461
462         <db path="person" schema="sparql-results" include="small" >
463             <criteria>?thing a bf:Person</criteria>
464             <index type="bf.person">
465                 ?thing bf:label %v FILTER(contains(%v, %s))
466             </index>
467         </db>
468
469         <db path="meeting" schema="sparql-results" include="small" >
470             <criteria>?thing a bf:Meeting</criteria>
471             <index type="bf.meeting">
472                 ?thing bf:label %v FILTER(contains(%v, %s))
473             </index>
474         </db>
475
476         <db path="agent" schema="sparql-results" include="small" >
477             <criteria>?thing a bf:Agent</criteria>
478             <index type="bf.agent">
479                 ?thing bf:label %v FILTER(contains(%v, %s))
480             </index>
481         </db>
482
483         <db path="event" schema="sparql-results" include="small" >
484             <criteria>?thing a bf:Event</criteria>
485             <index type="bf.event">
486                 ?thing bf:label %v FILTER(contains(%v, %s))
487             </index>
488         </db>
489
490         <db path="organization" schema="sparql-results" include="small" >
491             <criteria>?thing a bf:Organization</criteria>
492             <index type="bf.organization">
493                 ?thing bf:label %v FILTER(contains(%v, %s))
494             </index>
495         </db>
496
497         <db path="topic" schema="sparql-results" include="small" >
498             <criteria>?thing a bf:Topic</criteria>
499             <index type="bf.topic">
500                 ?thing bf:label %v FILTER(contains(%v, %s))
501             </index>
502         </db>
503
504         <!-- Title search, for seatching Title objects. -->
505         <!-- Not sure if this is needed, but it is a nice example -->
506         <db path="title" schema="sparql-results" include="smallbody" >
507             <criteria>?thing a bf:Title</criteria>
508
509             <index type="any">
510                 {
511                     ?thing bf:titleValue %v FILTER(contains(%v, %s))
512                 } UNION {
513                     ?thing bf:subtitle %v FILTER(contains(%v, %s))
514                 } UNION {
515                     ?thing bf:partTitle %v FILTER(contains(%v, %s))
516                 }
517             </index>
518
519             <index type="1016">
520                 {
521                     ?thing bf:titleValue %v FILTER(contains(%v, %s))
522                 } UNION {
523                     ?thing bf:subtitle %v FILTER(contains(%v, %s))
524                 } UNION {
525                     ?thing bf:partTitle %v FILTER(contains(%v, %s))
526                 }
527             </index>
528
529             <index type="bf.title">
530                 ?thing bf:titleValue %v FILTER(contains(%v, %s))
531             </index>
532
533             <index type="bf.subtitle">
534                 ?thing bf:subtitle %v FILTER(contains(%v, %s))
535             </index>
536
537             <index type="bf.parttitle">
538                 ?thing bf:partTitle %v FILTER(contains(%v, %s))
539             </index>
540         </db>
541
542         <!-- A hack to be able to look at any triplet in the base -->
543         <!-- TODO - Switch to the new system, probably using "small" -->
544         <db path="node" schema="sparql-results">
545             <prefix>rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns</prefix>
546             <prefix>bf: http://bibframe.org/vocab/</prefix>
547             <form>SELECT ?node ?rel ?obj</form>
548             <index type="any">?node ?rel ?obj FILTER( str(?node) = %s )</index>
549         </db>
550         <!-- A way to see which triplets refers to a given uri. -->
551         <!-- TODO - Switch to the new system, probably using "small" -->
552         <db path="ref" schema="sparql-results">
553             <prefix>rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns</prefix>
554             <prefix>bf: http://bibframe.org/vocab/</prefix>
555             <form>SELECT ?node ?rel ?obj</form>
556             <index type="any">?node ?rel ?obj FILTER( str(?obj) = %s )</index>
557         </db>
558     </filter>
559
560     <filter type="log">
561         <message>http</message>
562         <category apdu="true"/>
563     </filter>
564
565     <filter type="http_client">
566         <x-forwarded-for>true</x-forwarded-for>
567     </filter>
568 </filters>