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