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