4 Mp-sparql example configuration
6 This config file snippet is typically included from the main Metaproxy
7 configuration. It sets up a simple chain that consists of the sparql
8 filter to translate the queries etc, and a http_client filter that is used
9 to do the actual communication to the triple store.
11 This config provides quite many databases, one for each major type of
12 records. The most important are "work" and "instance". These have a great
13 number of indexes. There is a number of "small" databases like "person",
14 "meeting" and "topic". These have one main index, named after the database
15 name, for example "bf.person". The "node" database can search for any node
16 in the database, and "info" returns simple information about available
19 There are other databases defined in this file, but they are only used
20 internally, to be included in the real database definitions. All real,
21 searchable databases have
22 schema="sparql-results"
23 in the db tag, whereas those for include use only do not.
25 All databases support the BF-L ("Link") schema, which returns the triples
26 of the nodes found in the database, without expanding anything. Most of them
27 also support BF-V ("Verbose") schema that expands those links to return a set
28 of triples that is more or less self contained. A work, its instances, titles
29 for all of them, authors, and their names, etc.
36 <filters xmlns="http://indexdata.com/metaproxy">
37 <filter type="sparql">
39 <!-- Which sparql server to use, our demo, or your local installation -->
40 <!--defaults uri="http://bibframe.indexdata.com/sparql/"/-->
41 <defaults uri="http://localhost:8890/sparql/"/>
43 <!-- "thing" database that will be included all real databases -->
44 <db path="thing"> <!-- no schema, so it is not directly searchable -->
45 <prefix>bf: http://bibframe.org/vocab/</prefix>
46 <form>SELECT DISTINCT ?thing </form>
48 <!-- Common indexes -->
50 <!-- bf.uri is a simple way to get to a thing -->
52 ?thing %v_rel %v_obj FILTER( ?thing = %u )
55 <!-- bf.type is a simple way to search for types -->
56 <!-- for example, a bf.Work can also be bf:Text or bf:Audio -->
57 <index type="bf.type">
61 <!-- Find all nodes that refer to the given uri -->
62 <!-- useful after finding uris in the "small" bases -->
63 <!-- direct references only -->
69 <!-- The BF-L present format is the same for everything -->
70 <!-- Each db is supposed to provide a dedicated BF-V present format -->
82 <!-- "smallindex" db that will be included in work and instance -->
83 <!-- It provides the small indexes like bf.person, bf.place, etc -->
84 <!-- These match a person, etc, no matter what the relation to that -->
85 <!-- is, as long as there is a direct link -->
86 <!-- The %v gets assigned a new variable name, like ?v0. -->
87 <!-- The %vx gets the same ?v0, with the x suffixed to it, by regular -->
88 <!-- This way, we use a different variable for each index clause, and -->
89 <!-- do not get into trouble if we have an AND between two of the same kind -->
90 <db path="smallindex">
91 <index type="bf.person">
94 %vx bf:label %v FILTER(contains(%v, %s))
96 <index type="bf.topic">
99 %vx bf:label %v FILTER(contains(%v, %s))
101 <index type="bf.place">
104 %vx bf:label %v FILTER(contains(%v, %s))
106 <index type="bf.agent">
109 %vx bf:label %v FILTER(contains(%v, %s))
111 <index type="bf.meeting">
114 %vx bf:label %v FILTER(contains(%v, %s))
116 <index type="bf.organization">
118 %vx a bf:Organization .
119 %vx bf:label %v FILTER(contains(%v, %s))
121 <index type="bf.event">
124 %vx bf:label %v FILTER(contains(%v, %s))
128 <!-- work database -->
130 <db path="work" schema="sparql-results" include="thing smallindex">
132 <!-- The search clause just finds ?things, present is done below -->
133 <criteria>?thing a bf:Work</criteria>
135 <!-- Title indexes -->
136 <!-- These are messy, there are so many ways to get to a title -->
138 <!-- Main title. Looks logical, but in practice we have not seen -->
139 <!-- many of these -->
140 <index type="bf.title">
141 ?thing bf:title %v FILTER(contains(%v, %s))
144 <!-- worktitle.titleValue seems to be the most common way to -->
145 <!-- store the title of a work -->
146 <index type="bf.worktitle">
147 ?thing bf:workTitle %v_wt .
148 %v_wt bf:titleValue %v FILTER(contains(%v, %s))
151 <!-- Combining the two above, since users are not likely -->
152 <!-- to know how a given title has been indexed -->
153 <!-- TODO is "maintitle" a good name for this? I made it up myself -->
154 <index type="bf.maintitle">
156 ?thing bf:workTitle %v_wt .
157 %v_wt bf:titleValue %v FILTER(contains(%v, %s))
159 ?thing bf:title %v FILTER(contains(%v, %s))
163 <!-- the worktitle can also contain a subtitle and a parttitle -->
164 <index type="bf.subtitle">
165 ?thing bf:workTitle %v_wt .
166 %v_wt bf:subtitle %v FILTER(contains(%v, %s))
169 <index type="bf.parttitle">
170 ?thing bf:workTitle %v_wt .
171 %v_wt bf:partTitle %v FILTER(contains(%v, %s))
174 <!-- work.titlevariation - this could also have sub- and partTitles -->
175 <index type="bf.titlevariation">
176 ?thing bf:titleVariation %v_tv .
177 %v_tv bf:titleValue %v FILTER(contains(%v, %s))
180 <!-- Instance titles -->
181 <index type="bf.instancetitle">
182 %v_inst bf:instanceOf ?thing .
183 %v_inst bf:instanceTitle %v_tit .
184 %v_tit bf:titleValue %v FILTER(contains(%v, %s))
187 <!-- Combined title index. There are so many ways titles can be expresses
188 in Bibframe, this seems to cover most of what we have seen -->
189 <index type="bf.anytitle">
191 ?thing bf:title %v FILTER(contains(%v, %s))
192 } UNION { <!-- any kind of link -->
193 ?thing ?titlerel %v_ti . <!-- mostly workTitle, but others too -->
194 %v_ti a bf:Title <!-- to something that is a title -->
196 %v_ti bf:titleValue %v FILTER(contains(%v, %s))
198 %v_ti bf:partTitle %v FILTER(contains(%v, %s))
200 %v_ti bf:subtitle %v FILTER(contains(%v, %s))
203 %v_inst bf:instanceOf ?thing .
204 %v_inst bf:instanceTitle %v_ti .
205 %v_ti bf:titleValue %v FILTER(contains(%v, %s))
209 <!-- Author indexes. Much simpler than titles. -->
210 <index type="bf.creator">
211 ?thing bf:creator %v_c .
212 %v_c bf:label %v FILTER(contains(%v, %s))
215 <index type="bf.contributor">
216 ?thing bf:contributor %v_c .
217 %v_c bf:label %v FILTER(contains(%v, %s))
220 <index type="bf.anyauthor"> <!-- TODO - Is this a good name? -->
222 ?thing bf:creator %v_c .
223 %v_c bf:label %v FILTER(contains(%v, %s))
225 ?thing bf:contributor %v_c .
226 %v_c bf:label %v FILTER(contains(%v, %s))
231 <!-- Note that these refer to anything with a bf:subject relation -->
232 <!-- The actual item is likely to be something like topic person etc -->
233 <index type="bf.subject">
234 ?thing bf:subject %v_su .
235 %v_su bf:label %v FILTER(contains(%v, %s))
238 <!-- contentCategory can be searched with complete URIs like -->
239 <!-- http://id.loc.gov/vocabulary/contentTypes/txt -->
240 <index type="bf.contentcategory">
241 ?thing bf:contentCategory %u
244 <!-- Find the work that has a given Instance -->
245 <index type="bf.instance">
246 %v_inst bf:instanceOf ?thing FILTER ( %v_inst = %u)
249 <!-- Present formats -->
250 <!-- BF-L comes from the "thing" template -->
251 <!-- BF-V expands all links, even to instances but not other works -->
252 <present type="BF-V">
255 ?wobj1 ?wrel2 ?wobj2 .
256 ?wobj2 ?wrel3 ?wobj3 .
257 ?inst ?irel1 ?iobj1 .
258 ?iobj1 ?irel2 ?iobj2 .
267 MINUS { ?wobj1 a bf:Work }
268 MINUS { ?wobj1 a bf:Instance }
271 MINUS { ?wobj2 a bf:Work }
272 MINUS { ?wobj2 a bf:Instance }
275 <!-- Link to the instance(s) -->
277 ?inst bf:instanceOf %u .
281 MINUS { ?iobj1 a bf:Work }
282 MINUS { ?iobj1 a bf:Instance }
285 MINUS { ?iobj2 a bf:Work }
286 MINUS { ?iobj2 a bf:Instance }
294 <!-- Instance database -->
296 <db path="instance" schema="sparql-results" include="thing smallindex">
297 <criteria>?thing a bf:Instance</criteria>
299 <!-- Title indexes -->
300 <!-- These are messy, there are so many ways to get to a title -->
302 <!-- Main title. Looks logical. Many instances seem to have a title -->
303 <index type="bf.title">
304 ?thing bf:title %v FILTER(contains(%v, %s))
307 <!-- instancetitle is also pretty common -->
308 <index type="bf.instancetitle">
309 ?thing bf:instanceTitle %v_it .
310 %v_it bf:titleValue %v FILTER(contains(%v, %s))
313 <index type="bf.titlestatement">
314 ?thing bf:titleStatement %v FILTER(contains(%v, %s))
317 <!-- Combining the two above, since users are not likely to know how
318 a given title has been indexed -->
319 <index type="bf.maintitle">
321 ?thing bf:instanceTitle %v_it .
322 %v_it bf:titleValue %v FILTER(contains(%v, %s))
324 ?thing bf:title %v FILTER(contains(%v, %s))
329 <!-- the instancetitle can also contain a subtitle and a parttitle -->
330 <index type="bf.subtitle">
331 ?thing bf:instanceTitle %v_it .
332 %v_it bf:subtitle %v FILTER(contains(%v, %s))
335 <index type="bf.parttitle">
336 ?thing bf:instanceTitle %v_it .
337 %v_it bf:partTitle %v FILTER(contains(%v, %s))
339 <!-- We could also go to the works, and get those titles... -->
341 <!-- Combining any kind of title into one index -->
342 <index type="bf.anytitle">
344 ?thing bf:title %v FILTER(contains(%v, %s))
346 ?thing bf:titleStatement %v FILTER(contains(%v, %s))
348 ?thing ?titlerel %v_it . <!-- any kind of link -->
349 %v_it a bf:Title <!-- to something that is a title -->
351 %v_it bf:titleValue %v FILTER(contains(%v, %s))
353 %v_it bf:partTitle %v FILTER(contains(%v, %s))
355 %v_it bf:subtitle %v FILTER(contains(%v, %s))
360 <!-- Author indexes. Many instances don't have any, works do -->
361 <index type="bf.creator">
362 ?thing bf:creator %v_cr .
363 %v_cr bf:label %v FILTER(contains(%v, %s))
366 <index type="bf.workcreator">
367 ?thing bf:instanceOf %v_work .
368 %v_work bf:creator %v_cr .
369 %v_cr bf:label %v FILTER(contains(%v, %s))
372 <index type="bf.workcontributor">
373 ?thing bf:instanceOf %v_work .
374 %v_work bf:contributor %v_co .
375 %v_co bf:label %v FILTER(contains(%v, %s))
378 <index type="bf.contributor">
379 ?thing bf:contributor %v_co .
380 %v_co bf:label %v FILTER(contains(%v, %s))
383 <index type="bf.anyauthor">
385 ?thing bf:creator %v_cr .
386 %v_cr bf:label %v FILTER(contains(%v, %s))
388 ?thing bf:contributor %v_co .
389 %v_co bf:label %v FILTER(contains(%v, %s))
391 ?thing bf:instanceOf %v_work .
392 %v_work bf:creator %v_wcr .
393 %v_wcr bf:label %v FILTER(contains(%v, %s))
395 ?thing bf:instanceOf %v_work .
396 %v_work bf:contributor %v_wco .
397 %v_wco bf:label %v FILTER(contains(%v, %s))
401 <!-- isbn index. The Instance may contain a isbn10 or isbn13. -->
402 <!-- These can be literal values like -->
403 <!-- http://isbn.example.org/1906833214 which we need to search -->
404 <!-- by our usual substring match. Or they can be links to Identivfiers -->
405 <!-- which will have a proper identifierValue on which we can do -->
406 <!-- an exact match. -->
407 <index type="bf.isbn">
410 FILTER(isUri(%v) && contains(str(%v), %s))
413 FILTER(isUri(%v) && contains(str(%v), %s))
416 ?thing bf:isbn10 %v_isbn
418 ?thing bf:isbn13 %v_isbn
420 %v_isbn a bf:Identifier .
421 %v_isbn bf:identifierValue %v FILTER( %v = %s )
425 <!-- lccn number, a simpler index for id numbers -->
426 <index type="bf.lccn">
427 ?thing bf:lccn %v_lccn .
428 %v_lccn a bf:Identifier .
429 %v_lccn bf:identifierValue %v FILTER( %v = %s )
432 <!-- Find the instances of a given work -->
433 <index type="bf.work">
434 ?thing bf:instanceOf %u
438 <!-- Present formats. BF-L comes from "thing" -->
439 <!-- Full instance, with the related work too -->
440 <present type="BF-V">
443 ?iobj1 ?irel2 ?iobj2 .
444 ?iobj2 ?irel3 ?iobj3 .
445 ?work ?wrel1 ?wobj1 .
446 ?wobj1 ?wrel2 ?wobj2 .
454 MINUS { ?iobj2 a bf:Work }
455 MINUS { ?iobj2 a bf:Instance } .
458 MINUS { ?iobj3 a bf:Work }
459 MINUS { ?iobj3 a bf:Instance }
462 OPTIONAL { <!-- Work -->
463 %u bf:instanceOf ?work .
464 ?work ?wrel1 ?wobj1 .
467 MINUS { ?wobj1 a bf:Work }
468 MINUS { ?wobj1 a bf:Instance } .
471 MINUS { ?wobj2 a bf:Work }
472 MINUS { ?wobj2 a bf:Instance }
481 <!-- Small databases -->
483 <!-- "small" contains all the things common to all small databases -->
484 <!-- It is only to be used as an include, it is not searchable, since -->
485 <!-- it has no schema atribute -->
486 <!-- It is divided into "smallbody", and a "small" that includes -->
487 <!-- the general indexes, so that title searches can include the body, -->
488 <!-- but have different "any" indexes -->
490 <db path="smallbody" include="thing">
491 <present type="BF-V">
492 <!-- I don't think we need more than one level -->
493 <!--for these simple databases -->
500 OPTIONAL { ?obj ?rel1 ?obj1 }
505 <!-- The combined "small" database defaults -->
506 <db path="small" include="smallbody">
508 ?thing bf:label %v FILTER(contains(%v, %s))
511 ?thing bf:label %v FILTER(contains(%v, %s))
515 <!-- Various "small" databases, leaning heavily on the defaults above -->
516 <db path="place" schema="sparql-results" include="small" >
517 <criteria>?thing a bf:Place</criteria>
518 <index type="bf.place">
519 ?thing bf:label %v FILTER(contains(%v, %s))
523 <db path="person" schema="sparql-results" include="small" >
524 <criteria>?thing a bf:Person</criteria>
525 <index type="bf.person">
526 ?thing bf:label %v FILTER(contains(%v, %s))
530 <db path="meeting" schema="sparql-results" include="small" >
531 <criteria>?thing a bf:Meeting</criteria>
532 <index type="bf.meeting">
533 ?thing bf:label %v FILTER(contains(%v, %s))
537 <db path="agent" schema="sparql-results" include="small" >
538 <criteria>?thing a bf:Agent</criteria>
539 <index type="bf.agent">
540 ?thing bf:label %v FILTER(contains(%v, %s))
544 <db path="event" schema="sparql-results" include="small" >
545 <criteria>?thing a bf:Event</criteria>
546 <index type="bf.event">
547 ?thing bf:label %v FILTER(contains(%v, %s))
551 <db path="organization" schema="sparql-results" include="small" >
552 <criteria>?thing a bf:Organization</criteria>
553 <index type="bf.organization">
554 ?thing bf:label %v FILTER(contains(%v, %s))
558 <db path="topic" schema="sparql-results" include="small" >
559 <criteria>?thing a bf:Topic</criteria>
560 <index type="bf.topic">
561 ?thing bf:label %v FILTER(contains(%v, %s))
565 <!-- Title search, for seatching Title objects. -->
566 <!-- Not sure if this is needed, but it is a nice example -->
567 <db path="title" schema="sparql-results" include="smallbody" >
568 <criteria>?thing a bf:Title</criteria>
572 ?thing bf:titleValue %v FILTER(contains(%v, %s))
574 ?thing bf:subtitle %v FILTER(contains(%v, %s))
576 ?thing bf:partTitle %v FILTER(contains(%v, %s))
582 ?thing bf:titleValue %v FILTER(contains(%v, %s))
584 ?thing bf:subtitle %v FILTER(contains(%v, %s))
586 ?thing bf:partTitle %v FILTER(contains(%v, %s))
590 <index type="bf.title">
591 ?thing bf:titleValue %v FILTER(contains(%v, %s))
594 <index type="bf.subtitle">
595 ?thing bf:subtitle %v FILTER(contains(%v, %s))
598 <index type="bf.parttitle">
599 ?thing bf:partTitle %v FILTER(contains(%v, %s))
603 <!-- A hack to be able to look at any triplet in the base -->
604 <!-- The indexes bf.uri and bf.ref can also come in handy here -->
605 <db path="node" schema="sparql-results" include="smallbody">
607 ?thing ?rel ?obj FILTER( str(?thing) = %s )
614 <message>http</message>
617 <filter type="http_client">
618 <x-forwarded-for>true</x-forwarded-for>