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