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