+ <chapter id="examples">
+ <title>Example Configurations</title>
+
+ <sect1 id="examples-overview">
+ <title>Overview</title>
+
+ <para>
+ <command>zebraidx</command> and
+ <command>zebrasrv</command> are both
+ driven by a master configuration file, which may refer to other
+ subsidiary configuration files. By default, they try to use
+ <filename>zebra.cfg</filename> in the working directory as the
+ master file; but this can be changed using the <literal>-c</literal>
+ option to specify an alternative master configuration file.
+ </para>
+ <para>
+ The master configuration file tells &zebra;:
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Where to find subsidiary configuration files, including both
+ those that are named explicitly and a few ``magic'' files such
+ as <literal>default.idx</literal>,
+ which specifies the default indexing rules.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ What record schemas to support. (Subsidiary files specify how
+ to index the contents of records in those schemas, and what
+ format to use when presenting records in those schemas to client
+ software.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ What attribute sets to recognise in searches. (Subsidiary files
+ specify how to interpret the attributes in terms
+ of the indexes that are created on the records.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Policy details such as what type of input format to expect when
+ adding new records, what low-level indexing algorithm to use,
+ how to identify potential duplicate records, etc.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+ <para>
+ Now let's see what goes in the <literal>zebra.cfg</literal> file
+ for some example configurations.
+ </para>
+ </sect1>
+
+ <sect1 id="example1">
+ <title>Example 1: &acro.xml; Indexing And Searching</title>
+
+ <para>
+ This example shows how &zebra; can be used with absolutely minimal
+ configuration to index a body of
+ <ulink url="&url.xml;">&acro.xml;</ulink>
+ documents, and search them using
+ <ulink url="&url.xpath;">XPath</ulink>
+ expressions to specify access points.
+ </para>
+ <para>
+ Go to the <literal>examples/zthes</literal> subdirectory
+ of the distribution archive.
+ There you will find a <literal>Makefile</literal> that will
+ populate the <literal>records</literal> subdirectory with a file of
+ <ulink url="http://zthes.z3950.org/">Zthes</ulink>
+ records representing a taxonomic hierarchy of dinosaurs. (The
+ records are generated from the family tree in the file
+ <literal>dino.tree</literal>.)
+ Type <literal>make records/dino.xml</literal>
+ to make the &acro.xml; data file.
+ (Or you could just type <literal>make dino</literal> to build the &acro.xml;
+ data file, create the database and populate it with the taxonomic
+ records all in one shot - but then you wouldn't learn anything,
+ would you? :-)
+ </para>
+ <para>
+ Now we need to create a &zebra; database to hold and index the &acro.xml;
+ records. We do this with the
+ &zebra; indexer, <command>zebraidx</command>, which is
+ driven by the <literal>zebra.cfg</literal> configuration file.
+ For our purposes, we don't need any
+ special behaviour - we can use the defaults - so we can start with a
+ minimal file that just tells <command>zebraidx</command> where to
+ find the default indexing rules, and how to parse the records:
+ <screen>
+ profilePath: .:../../tab
+ recordType: grs.sgml
+ </screen>
+ </para>
+ <para>
+ That's all you need for a minimal &zebra; configuration. Now you can
+ roll the &acro.xml; records into the database and build the indexes:
+ <screen>
+ zebraidx update records
+ </screen>
+ </para>
+ <para>
+ Now start the server. Like the indexer, its behaviour is
+ controlled by the
+ <literal>zebra.cfg</literal> file; and like the indexer, it works
+ just fine with this minimal configuration.
+ <screen>
+ zebrasrv
+ </screen>
+ By default, the server listens on IP port number 9999, although
+ this can easily be changed - see
+ <xref linkend="zebrasrv"/>.
+ </para>
+ <para>
+ Now you can use the &acro.z3950; client program of your choice to execute
+ XPath-based boolean queries and fetch the &acro.xml; records that satisfy
+ them:
+ <screen>
+ $ yaz-client @:9999
+ Connecting...Ok.
+ Z> find @attr 1=/Zthes/termName Sauroposeidon
+ Number of hits: 1
+ Z> format xml
+ Z> show 1
+ <Zthes>
+ <termId>22</termId>
+ <termName>Sauroposeidon</termName>
+ <termType>PT</termType>
+ <termNote>The tallest known dinosaur (18m)</termNote>
+ <relation>
+ <relationType>BT</relationType>
+ <termId>21</termId>
+ <termName>Brachiosauridae</termName>
+ <termType>PT</termType>
+ </relation>
+
+ <idzebra xmlns="http://www.indexdata.dk/zebra/">
+ <size>300</size>
+ <localnumber>23</localnumber>
+ <filename>records/dino.xml</filename>
+ </idzebra>
+ </Zthes>
+ </screen>
+ </para>
+ <para>
+ Now wasn't that nice and easy?
+ </para>
+ </sect1>
+
+
+ <sect1 id="example2">
+ <title>Example 2: Supporting Interoperable Searches</title>
+
+ <para>
+ The problem with the previous example is that you need to know the
+ structure of the documents in order to find them. For example,
+ when we wanted to find the record for the taxon
+ <foreignphrase role="taxon">Sauroposeidon</foreignphrase>,
+ we had to formulate a complex XPath
+ <literal>/Zthes/termName</literal>
+ which embodies the knowledge that taxon names are specified in a
+ <literal><termName></literal> element inside the top-level
+ <literal><Zthes></literal> element.
+ </para>
+ <para>
+ This is bad not just because it requires a lot of typing, but more
+ significantly because it ties searching semantics to the physical
+ structure of the searched records. You can't use the same search
+ specification to search two databases if their internal
+ representations are different. Consider a different taxonomy
+ database in which the records have taxon names specified
+ inside a <literal><name></literal> element nested within a
+ <literal><identification></literal> element
+ inside a top-level <literal><taxon></literal> element: then
+ you'd need to search for them using
+ <literal>1=/taxon/identification/name</literal>
+ </para>
+ <para>
+ How, then, can we build broadcasting Information Retrieval
+ applications that look for records in many different databases?
+ The &acro.z3950; protocol offers a powerful and general solution to this:
+ abstract ``access points''. In the &acro.z3950; model, an access point
+ is simply a point at which searches can be directed. Nothing is
+ said about implementation: in a given database, an access point
+ might be implemented as an index, a path into physical records, an
+ algorithm for interrogating relational tables or whatever works.
+ The only important thing is that the semantics of an access
+ point is fixed and well defined.
+ </para>
+ <para>
+ For convenience, access points are gathered into <firstterm>attribute
+ sets</firstterm>. For example, the &acro.bib1; attribute set is supposed to
+ contain bibliographic access points such as author, title, subject
+ and ISBN; the GEO attribute set contains access points pertaining
+ to geospatial information (bounding coordinates, stratum, latitude
+ resolution, etc.); the CIMI
+ attribute set contains access points to do with museum collections
+ (provenance, inscriptions, etc.)
+ </para>
+ <para>
+ In practice, the &acro.bib1; attribute set has tended to be a dumping
+ ground for all sorts of access points, so that, for example, it
+ includes some geospatial access points as well as strictly
+ bibliographic ones. Nevertheless, this model
+ allows a layer of abstraction over the physical representation of
+ records in databases.
+ </para>
+ <para>
+ In the &acro.bib1; attribute set, a taxon name is probably best
+ interpreted as a title - that is, a phrase that identifies the item
+ in question. &acro.bib1; represents title searches by
+ access point 4. (See
+ <ulink url="&url.z39.50.bib1.semantics;">The &acro.bib1; Attribute
+ Set Semantics</ulink>)
+ So we need to configure our dinosaur database so that searches for
+ &acro.bib1; access point 4 look in the
+ <literal><termName></literal> element,
+ inside the top-level
+ <literal><Zthes></literal> element.
+ </para>
+ <para>
+ This is a two-step process. First, we need to tell &zebra; that we
+ want to support the &acro.bib1; attribute set. Then we need to tell it
+ which elements of its record pertain to access point 4.
+ </para>
+ <para>
+ We need to create an <link linkend="abs-file">Abstract Syntax
+ file</link> named after the document element of the records we're
+ working with, plus a <literal>.abs</literal> suffix - in this case,
+ <literal>Zthes.abs</literal> - as follows:
+ </para>
+ <programlistingco>
+ <areaspec>
+ <area id="attset.zthes" coords="2"/>
+ <area id="attset.attset" coords="3"/>
+ <area id="termId" coords="7"/>
+ <area id="termName" coords="8"/>
+ </areaspec>
+ <programlisting>
+ attset zthes.att
+ attset bib1.att
+ xpath enable
+ systag sysno none
+
+ xelm /Zthes/termId termId:w
+ xelm /Zthes/termName termName:w,title:w
+ xelm /Zthes/termQualifier termQualifier:w
+ xelm /Zthes/termType termType:w
+ xelm /Zthes/termLanguage termLanguage:w
+ xelm /Zthes/termNote termNote:w
+ xelm /Zthes/termCreatedDate termCreatedDate:w
+ xelm /Zthes/termCreatedBy termCreatedBy:w
+ xelm /Zthes/termModifiedDate termModifiedDate:w
+ xelm /Zthes/termModifiedBy termModifiedBy:w
+ </programlisting>
+ <calloutlist>
+ <callout arearefs="attset.zthes">