ac5b4920e2495cd439fbe75253f3312c014844b3
[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                 }
167             </index>
168
169             <!-- Author indexes. Much simpler than titles. -->
170             <index type="bf.creator">
171                 ?thing bf:creator %v_c .
172                 %v_c bf:label %v FILTER(contains(%v, %s))
173             </index>
174
175             <index type="bf.contributor">
176                 ?thing bf:contributor %v_c .
177                 %v_c bf:label %v FILTER(contains(%v, %s))
178             </index>
179
180             <index type="bf.anyauthor"> <!-- TODO - Is this a good name? -->
181                 {
182                     ?thing bf:creator %v_c .
183                     %v_c bf:label %v FILTER(contains(%v, %s))
184                 } UNION {
185                     ?thing bf:contributor %v_c .
186                     %v_c bf:label %v FILTER(contains(%v, %s))
187                 }
188             </index>
189
190             <!-- Subjects -->
191             <!-- Note that these refer to anything with a bf:subject relation -->
192             <!-- The actual item is likely to be something like topic person etc -->
193             <index type="bf.subject">
194                 ?thing bf:subject %v_su .
195                 %v_su bf:label %v FILTER(contains(%v, %s))
196             </index>
197
198             <!-- contentCategory can be searched with complete URIs like -->
199             <!-- http://id.loc.gov/vocabulary/contentTypes/txt -->
200             <index type="bf.contentcategory">
201                 ?thing bf:contentCategory %u
202             </index>
203
204             <!-- Present formats -->
205             <!-- BF-L comes from the "thing" template -->
206             <!-- BF-V expands all links, even to instances but not other works -->
207             <present type="BF-V">
208                 CONSTRUCT {
209                     %u ?wrel1 ?wobj1 .
210                     ?wobj1 ?wrel2 ?wobj2 .
211                     ?wobj2 ?wrel3 ?wobj3 .
212                     ?inst ?irel1 ?iobj1 .
213                     ?iobj1 ?irel2 ?iobj2 .
214                     ?iobj2 ?irel3 ?iobj3
215                 }
216                 WHERE {
217                     %u a bf:Work .
218                     %u ?wrel1 ?wobj1 .
219
220                     OPTIONAL {
221                         ?wobj1 ?wrel2 ?wobj2
222                             MINUS { ?wobj1 a bf:Work }
223                             MINUS { ?wobj1 a bf:Instance }
224                         OPTIONAL {
225                             ?wobj2 ?wrel3 ?wobj3
226                                 MINUS { ?wobj2 a bf:Work }
227                                 MINUS { ?wobj2 a bf:Instance }
228                         }
229                     }
230                     <!-- Link to the instance(s) -->
231                     OPTIONAL {
232                         ?inst bf:instanceOf %u .
233                         ?inst ?irel1 ?iobj1
234                         OPTIONAL {
235                             ?iobj1 ?irel2 ?iobj2
236                                 MINUS { ?iobj1 a bf:Work }
237                                 MINUS { ?iobj1 a bf:Instance }
238                             OPTIONAL {
239                                 ?iobj2 ?irel3 ?iobj3
240                                     MINUS { ?iobj2 a bf:Work }
241                                     MINUS { ?iobj2 a bf:Instance }
242                             }
243                         }
244                     }
245                 }
246             </present>
247         </db>
248
249         <!-- Instance database -->
250
251         <db path="instance" schema="sparql-results" include="thing smallindex">
252             <criteria>?thing a bf:Instance</criteria>
253
254             <!-- Title indexes -->
255             <!-- These are messy, there are so many ways to get to a title -->
256
257             <!-- Main title. Looks logical. Many instances seem to have a title -->
258             <index type="bf.title">
259                 ?thing bf:title %v FILTER(contains(%v, %s))
260             </index>
261
262             <!-- instancetitle is also pretty common -->
263             <index type="bf.instancetitle">
264                 ?thing bf:instanceTitle %v_it .
265                 %v_it bf:titleValue %v FILTER(contains(%v, %s))
266             </index>
267
268             <index type="bf.titlestatement">
269                 ?thing bf:titleStatement %v FILTER(contains(%v, %s))
270             </index>
271
272             <!-- Combining the two above, since users are not likely to know how
273             a given title has been indexed -->
274             <index type="bf.maintitle">
275                 {
276                     ?thing bf:instanceTitle %v_it .
277                     %v_it bf:titleValue %v FILTER(contains(%v, %s))
278                 } UNION {
279                     ?thing bf:title %v FILTER(contains(%v, %s))
280                 }
281             </index>
282
283
284             <!-- the instancetitle can also contain a subtitle and a parttitle -->
285             <index type="bf.subtitle">
286                 ?thing bf:instanceTitle %v_it .
287                 %v_it bf:subtitle %v FILTER(contains(%v, %s))
288             </index>
289
290             <index type="bf.parttitle">
291                 ?thing bf:instanceTitle %v_it .
292                 %v_it bf:partTitle %v FILTER(contains(%v, %s))
293             </index>
294             <!-- We could also go to the works, and get those titles... -->
295
296             <!-- Combining any kind of title into one index -->
297             <index type="bf.anytitle">
298                 {
299                     ?thing bf:title %v FILTER(contains(%v, %s))
300                 } UNION {
301                     ?thing bf:titleStatement %v FILTER(contains(%v, %s))
302                 } UNION {
303                     ?thing ?titlerel %v_it . <!-- any kind of link -->
304                     %v_it a bf:Title <!-- to something that is a title -->
305                     {
306                         %v_it bf:titleValue %v FILTER(contains(%v, %s))
307                     } UNION {
308                         %v_it bf:partTitle %v FILTER(contains(%v, %s))
309                     } UNION {
310                         %v_it bf:subtitle %v FILTER(contains(%v, %s))
311                     }
312                 }
313             </index>
314
315             <!-- Author indexes. Many instances don't have any, works do -->
316             <index type="bf.creator">
317                 ?thing bf:creator %v_cr .
318                 %v_cr bf:label %v FILTER(contains(%v, %s))
319             </index>
320
321             <index type="bf.workcreator">
322                 ?thing bf:instanceOf %v_work .
323                 %v_work bf:creator %v_cr .
324                 %v_cr bf:label %v FILTER(contains(%v, %s))
325             </index>
326
327             <index type="bf.workcontributor">
328                 ?thing bf:instanceOf %v_work .
329                 %v_work bf:contributor %v_co .
330                 %v_co bf:label %v FILTER(contains(%v, %s))
331             </index>
332
333             <index type="bf.contributor">
334                 ?thing bf:contributor %v_co .
335                 %v_co bf:label %v FILTER(contains(%v, %s))
336             </index>
337
338             <index type="bf.anyauthor">
339                 {
340                     ?thing bf:creator %v_cr .
341                     %v_cr bf:label %v FILTER(contains(%v, %s))
342                 } UNION {
343                     ?thing bf:contributor %v_co .
344                     %v_co bf:label %v FILTER(contains(%v, %s))
345                 } UNION {
346                     ?thing bf:instanceOf %v_work .
347                     %v_work bf:creator %v_wcr .
348                     %v_wcr bf:label %v FILTER(contains(%v, %s))
349                 } UNION {
350                     ?thing bf:instanceOf %v_work .
351                     %v_work bf:contributor %v_wco .
352                     %v_wco bf:label %v FILTER(contains(%v, %s))
353                 }
354             </index>
355
356             <!-- isbn index. The Instance may contain a isbn10 or isbn13. -->
357             <!-- These can be literal values like -->
358             <!--   http://isbn.example.org/1906833214 which we need to search -->
359             <!-- by our usual substring match. Or they can be links to Identivfiers -->
360             <!-- which will have a proper identifierValue on which we can do -->
361             <!-- an exact match.  -->
362             <index type="bf.isbn">
363                 {
364                     ?thing bf:isbn10  %v
365                         FILTER(isUri(%v) &amp;&amp; contains(str(%v), %s))
366                 } UNION {
367                     ?thing bf:isbn13  %v
368                         FILTER(isUri(%v) &amp;&amp; contains(str(%v), %s))
369                 } UNION {
370                     {
371                         ?thing bf:isbn10 %v_isbn
372                     } UNION {
373                         ?thing bf:isbn13 %v_isbn
374                     }
375                     %v_isbn a bf:Identifier  .
376                     %v_isbn bf:identifierValue  %v FILTER( %v = %s )
377                 }
378             </index>
379             
380             <!-- lccn number, a simpler index for id numbers -->
381             <index type="bf.lccn">
382                 ?thing bf:lccn %v_lccn .
383                 %v_lccn a bf:Identifier  .
384                 %v_lccn bf:identifierValue  %v FILTER( %v = %s )
385             </index>
386
387
388             <!-- Present formats. BF-L comes from "thing" -->
389             <!-- Full instance, with the related work too -->
390             <present type="BF-V">
391                 CONSTRUCT {
392                     %u ?irel1 ?iobj1 .
393                     ?iobj1 ?irel2 ?iobj2 .
394                     ?iobj2 ?irel3 ?iobj3 .
395                     ?work ?wrel1 ?wobj1 .
396                     ?wobj1 ?wrel2 ?wobj2 .
397                     ?wobj2 ?wrel3 ?wobj3
398                 }
399                 WHERE {
400                     %u a bf:Instance .
401                     %u ?irel1 ?iobj1 .
402                     OPTIONAL {
403                         ?iobj1 ?irel2 ?iobj2
404                             MINUS { ?iobj2 a bf:Work }
405                             MINUS { ?iobj2 a bf:Instance } .
406                         OPTIONAL {
407                             ?iobj2 ?irel3 ?iobj3
408                                 MINUS { ?iobj3 a bf:Work }
409                                 MINUS { ?iobj3 a bf:Instance }
410                         }
411                     }
412                     OPTIONAL { <!-- Work -->
413                         %u bf:instanceOf ?work .
414                         ?work ?wrel1 ?wobj1 .
415                         OPTIONAL {
416                             ?wobj1 ?wrel2 ?wobj2
417                                 MINUS { ?wobj1 a bf:Work }
418                                 MINUS { ?wobj1 a bf:Instance } .
419                             OPTIONAL {
420                                 ?wobj2 ?wrel3 ?wobj3
421                                     MINUS { ?wobj2 a bf:Work }
422                                     MINUS { ?wobj2 a bf:Instance }
423                             }
424                         }
425                     }
426                 }
427             </present>
428
429         </db>
430
431         <!-- Small databases -->
432
433         <!-- "small" contains all the things common to all small databases -->
434         <!-- It is only to be used as an include, it is not searchable, since -->
435         <!-- it has no schema atribute -->
436         <!-- It is divided into "smallbody", and a "small" that includes -->
437         <!-- the general indexes, so that title searches can include the body, -->
438         <!-- but have different "any" indexes -->
439
440         <db path="smallbody" include="thing">
441             <present type="BF-V">
442                 <!-- I don't think we need more than one level -->
443                 <!--for these simple databases -->
444                 CONSTRUCT {
445                     %u ?rel ?obj .
446                     ?obj ?rel1 ?obj1 .
447                 }
448                 WHERE {
449                     %u ?rel ?obj .
450                     OPTIONAL { ?obj ?rel1 ?obj1 }
451                 }
452             </present>
453         </db>
454
455         <!-- The combined "small" database defaults -->
456         <db path="small" include="smallbody">
457             <index type="any">
458                 ?thing bf:label %v FILTER(contains(%v, %s))
459             </index>
460             <index type="1016">
461                 ?thing bf:label %v FILTER(contains(%v, %s))
462             </index>
463         </db>
464
465         <!-- Various "small" databases, leaning heavily on the defaults above -->
466         <db path="place" schema="sparql-results" include="small" >
467             <criteria>?thing a bf:Place</criteria>
468             <index type="bf.place">
469                 ?thing bf:label %v FILTER(contains(%v, %s))
470             </index>
471         </db>
472
473         <db path="person" schema="sparql-results" include="small" >
474             <criteria>?thing a bf:Person</criteria>
475             <index type="bf.person">
476                 ?thing bf:label %v FILTER(contains(%v, %s))
477             </index>
478         </db>
479
480         <db path="meeting" schema="sparql-results" include="small" >
481             <criteria>?thing a bf:Meeting</criteria>
482             <index type="bf.meeting">
483                 ?thing bf:label %v FILTER(contains(%v, %s))
484             </index>
485         </db>
486
487         <db path="agent" schema="sparql-results" include="small" >
488             <criteria>?thing a bf:Agent</criteria>
489             <index type="bf.agent">
490                 ?thing bf:label %v FILTER(contains(%v, %s))
491             </index>
492         </db>
493
494         <db path="event" schema="sparql-results" include="small" >
495             <criteria>?thing a bf:Event</criteria>
496             <index type="bf.event">
497                 ?thing bf:label %v FILTER(contains(%v, %s))
498             </index>
499         </db>
500
501         <db path="organization" schema="sparql-results" include="small" >
502             <criteria>?thing a bf:Organization</criteria>
503             <index type="bf.organization">
504                 ?thing bf:label %v FILTER(contains(%v, %s))
505             </index>
506         </db>
507
508         <db path="topic" schema="sparql-results" include="small" >
509             <criteria>?thing a bf:Topic</criteria>
510             <index type="bf.topic">
511                 ?thing bf:label %v FILTER(contains(%v, %s))
512             </index>
513         </db>
514
515         <!-- Title search, for seatching Title objects. -->
516         <!-- Not sure if this is needed, but it is a nice example -->
517         <db path="title" schema="sparql-results" include="smallbody" >
518             <criteria>?thing a bf:Title</criteria>
519
520             <index type="any">
521                 {
522                     ?thing bf:titleValue %v FILTER(contains(%v, %s))
523                 } UNION {
524                     ?thing bf:subtitle %v FILTER(contains(%v, %s))
525                 } UNION {
526                     ?thing bf:partTitle %v FILTER(contains(%v, %s))
527                 }
528             </index>
529
530             <index type="1016">
531                 {
532                     ?thing bf:titleValue %v FILTER(contains(%v, %s))
533                 } UNION {
534                     ?thing bf:subtitle %v FILTER(contains(%v, %s))
535                 } UNION {
536                     ?thing bf:partTitle %v FILTER(contains(%v, %s))
537                 }
538             </index>
539
540             <index type="bf.title">
541                 ?thing bf:titleValue %v FILTER(contains(%v, %s))
542             </index>
543
544             <index type="bf.subtitle">
545                 ?thing bf:subtitle %v FILTER(contains(%v, %s))
546             </index>
547
548             <index type="bf.parttitle">
549                 ?thing bf:partTitle %v FILTER(contains(%v, %s))
550             </index>
551         </db>
552
553         <!-- A hack to be able to look at any triplet in the base -->
554         <db path="node" schema="sparql-results" include="smallbody">
555             <index type="any">
556                 ?thing ?rel ?obj FILTER( str(?thing) = %s )
557             </index>
558         </db>
559         <!-- A way to see which triplets refers to a given uri. -->
560         <db path="ref" schema="sparql-results" include="smallbody">
561             <index type="any">
562                 ?thing ?rel ?obj FILTER( str(?obj) = %s )
563             </index>
564         </db>
565     </filter>
566
567     <filter type="log">
568         <message>http</message>
569         <category apdu="true"/>
570     </filter>
571
572     <filter type="http_client">
573         <x-forwarded-for>true</x-forwarded-for>
574     </filter>
575 </filters>