[hibernate-commits] Hibernate SVN: r14021 - in search/trunk/doc/reference/en: modules and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sun Sep 23 16:17:51 EDT 2007


Author: epbernard
Date: 2007-09-23 16:17:51 -0400 (Sun, 23 Sep 2007)
New Revision: 14021

Modified:
   search/trunk/doc/reference/en/master.xml
   search/trunk/doc/reference/en/modules/architecture.xml
   search/trunk/doc/reference/en/modules/batchindex.xml
   search/trunk/doc/reference/en/modules/configuration.xml
   search/trunk/doc/reference/en/modules/getting-started.xml
   search/trunk/doc/reference/en/modules/mapping.xml
   search/trunk/doc/reference/en/modules/query.xml
Log:
Documentation update

Modified: search/trunk/doc/reference/en/master.xml
===================================================================
--- search/trunk/doc/reference/en/master.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/master.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -19,7 +19,7 @@
 
     <subtitle>Reference Guide</subtitle>
 
-    <releaseinfo>3.0.0.CR1</releaseinfo>
+    <releaseinfo>3.0.0.GA</releaseinfo>
 
     <mediaobject>
       <imageobject>

Modified: search/trunk/doc/reference/en/modules/architecture.xml
===================================================================
--- search/trunk/doc/reference/en/modules/architecture.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/architecture.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -2,79 +2,81 @@
 <!--  $Id$ -->
 <chapter id="search-architecture">
   <title>Architecture</title>
+
   <section>
     <title>Overview</title>
-    
-  <para>Hibernate Search consists of an indexing and an index search
-  engine. Both are backed by Apache Lucene.</para>
 
-  <para>When an entity is inserted, updated or removed in the database,
-  Hibernate Search keeps track of this event (through the Hibernate event
-  system) and schedules an index update. All the index updates are handled for
-  you without you having to use the Apache Lucene APIs 
-  (see <xref linkend="search-configuration-event"/>).
-  </para>
+    <para>Hibernate Search consists of an indexing and an index search engine.
+    Both are backed by Apache Lucene.</para>
 
-  <para>To interact with Apache Lucene indexes, Hibernate Search has the
-  notion of <classname>DirectoryProvider</classname>s. A directory provider
-  will manage a given Lucene <classname>Directory</classname> type. You can
-  configure directory providers to adjust the directory target
-  (see <xref linkend="search-configuration-directory"/>).</para>
+    <para>When an entity is inserted, updated or removed in/from the database,
+    Hibernate Search keeps track of this event (through the Hibernate event
+    system) and schedules an index update. All the index updates are handled
+    for you without you having to use the Apache Lucene APIs (see <xref
+    linkend="search-configuration-event" />).</para>
 
-  <para>Next to the index updates Hibernate Search can also use the Lucene index to search an entity and
-  return a list of managed entities saving you the tedious object to
-  Lucene document mapping. The same persistence
-  context is shared between Hibernate and Hibernate Search; as a matter of
-  fact, the Search Session is built on top of the Hibernate Session. The
-  application code use the unified <classname>org.hibernate.Query</classname>
-  or <classname>javax.persistence.Query</classname> APIs exactly the way a
-  HQL, JPA-QL or native queries would do.</para>
+    <para>To interact with Apache Lucene indexes, Hibernate Search has the
+    notion of <classname>DirectoryProvider</classname>s. A directory provider
+    will manage a given Lucene <classname>Directory</classname> type. You can
+    configure directory providers to adjust the directory target (see <xref
+    linkend="search-configuration-directory" />).</para>
 
-  <para>To be more efficient, Hibernate Search batches the write interactions
-  with the Lucene index. There is currently two types of batching depending
-  on the expected scope.</para>
+    <para>Hibernate Search can also use the Lucene index to search an entity
+    and return a list of managed entities saving you the tedious object to
+    Lucene document mapping. The same persistence context is shared between
+    Hibernate and Hibernate Search; as a matter of fact, the Search Session is
+    built on top of the Hibernate Session. The application code use the
+    unified <classname>org.hibernate.Query</classname> or
+    <classname>javax.persistence.Query</classname> APIs exactly the way a HQL,
+    JPA-QL or native queries would do.</para>
 
-  <para>Outside an transaction, the index update operation is executed
-  right after the actual database operation. This scope is really a no
-  scoping setup and no batching is performed.</para>
+    <para>To be more efficient, Hibernate Search batches the write
+    interactions with the Lucene index. There is currently two types of
+    batching depending on the expected scope.</para>
 
-  <para>It is however recommended, for both your database and Hibernate
-  Search, to execute your operation in a transaction be it JDBC or
-  JTA. When in a transaction, the index update operation is scheduled for
-  the transaction commit and discarded in case of transaction rollback.
-  The batching scope is the transaction. There are two immediate
-  benefits:</para>
+    <para>Outside a transaction, the index update operation is executed right
+    after the actual database operation. This scope is really a no scoping
+    setup and no batching is performed.</para>
 
-  <itemizedlist>
-    <listitem>
-      <para>Performance: Lucene indexing works better when operation are
-      executed in batch.</para>
-    </listitem>
+    <para>It is however recommended, for both your database and Hibernate
+    Search, to execute your operation in a transaction be it JDBC or JTA. When
+    in a transaction, the index update operation is scheduled for the
+    transaction commit and discarded in case of transaction rollback. The
+    batching scope is the transaction. There are two immediate
+    benefits:</para>
 
-    <listitem>
-      <para>ACIDity: The work executed has the same scoping as the one
-      executed by the database transaction and is executed if and only if
-      the transaction is committed.</para>
+    <itemizedlist>
+      <listitem>
+        <para>Performance: Lucene indexing works better when operation are
+        executed in batch.</para>
+      </listitem>
 
-      <note>
-        <para>Disclaimer, the work in not ACID in the strict sense of it,
-        but ACID behavior is rarely useful for full text search indexes
-        since they can be rebuilt from the source at any time.</para>
-      </note>
-    </listitem>
-  </itemizedlist>
+      <listitem>
+        <para>ACIDity: The work executed has the same scoping as the one
+        executed by the database transaction and is executed if and only if
+        the transaction is committed.</para>
 
-  <para>You can think of those two scopes (no scope vs transactional) as the
-  equivalent of the (infamous) autocommit vs transactional behavior. From a
-  performance perspective, the <emphasis>in transaction</emphasis> mode is
-  recommended. The scoping choice is made transparently: Hibernate Search
-  detects the presence of a transaction and adjust the scoping.</para>
+        <note>
+          <para>Disclaimer, the work in not ACID in the strict sense of it,
+          but ACID behavior is rarely useful for full text search indexes
+          since they can be rebuilt from the source at any time.</para>
+        </note>
+      </listitem>
+    </itemizedlist>
 
-  <note>Hibernate Search works perfectly fine in the Hibernate /
-  EntityManager long conversation pattern aka. atomic conversation.</note>
+    <para>You can think of those two scopes (no scope vs transactional) as the
+    equivalent of the (infamous) autocommit vs transactional behavior. From a
+    performance perspective, the <emphasis>in transaction</emphasis> mode is
+    recommended. The scoping choice is made transparently: Hibernate Search
+    detects the presence of a transaction and adjust the scoping.</para>
 
-  <note>Depending on user demand, additional scoping will be considered, the
-  pluggability mechanism being already in place.</note>
+    <note>
+      Hibernate Search works perfectly fine in the Hibernate / EntityManager long conversation pattern aka. atomic conversation.
+    </note>
+
+    <note>
+      Depending on user demand, additional scoping will be considered, the pluggability mechanism being already in place.
+    </note>
   </section>
 
   <section>
@@ -90,8 +92,8 @@
       <para>In this mode, all index update operations applied on a given node
       (JVM) will be executed to the Lucene directories (through the directory
       providers) by the same node. This mode is typically used in non
-      clustered environment or in clustered environments where the directory store is
-      shared.</para>
+      clustered environment or in clustered environments where the directory
+      store is shared.</para>
 
       <mediaobject>
         <imageobject role="html">
@@ -123,8 +125,8 @@
       basis to the slave copies. This is known as the master / slaves pattern.
       The master is the sole responsible for updating the Lucene index. The
       slaves can accept read as well as write operations. However, they only
-      process the read operation on their local index copy and delegate the update 
-      operations to the master.</para>
+      process the read operation on their local index copy and delegate the
+      update operations to the master.</para>
 
       <mediaobject>
         <imageobject role="html">
@@ -145,9 +147,8 @@
     </section>
 
     <note>Hibernate Search is an extensible architecture. While not yet part
-    of the public API, plugging a third party back end is possible. Feel
-    free to drop ideas to
-    <literal>hibernate-dev at lists.jboss.org</literal>.</note>
+    of the public API, plugging a third party back end is possible. Feel free
+    to drop ideas to <literal>hibernate-dev at lists.jboss.org</literal>.</note>
   </section>
 
   <section>
@@ -178,9 +179,9 @@
       small overhead is introduced to deal with thread management.</para>
 
       <para>It is recommended to use synchronous execution first and evaluate
-      asynchronous execution if performance problems occur and after having set up a
-      proper benchmark (ie not a lonely cowboy hitting the system in a
-      completely unrealistic way).</para>
+      asynchronous execution if performance problems occur and after having
+      set up a proper benchmark (ie not a lonely cowboy hitting the system in
+      a completely unrealistic way).</para>
     </section>
   </section>
 
@@ -190,7 +191,8 @@
     <para>When executing a query, Hibernate Search interacts with the Apache
     Lucene indexes through a reader strategy. chosing a reader strategy will
     depend on the profile of the application (frequent updates, read mostly,
-    asynchronous index update etc). See also <xref linkend="configuration-reader-strategy"/></para>
+    asynchronous index update etc). See also <xref
+    linkend="configuration-reader-strategy" /></para>
 
     <section>
       <title>Shared</title>

Modified: search/trunk/doc/reference/en/modules/batchindex.xml
===================================================================
--- search/trunk/doc/reference/en/modules/batchindex.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/batchindex.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -6,10 +6,10 @@
   <section id="search-batchindex-indexing">
     <title>Indexing</title>
 
-    <para>It is sometimes useful to index an object event if this object is
-    not inserted nor updated to the database. This is especially true when you
-    want to build your index the first time. You can achieve that goal using
-    the <classname>FullTextSession</classname> .</para>
+    <para>It is sometimes useful to index an object even if this object is not
+    inserted nor updated to the database. This is especially true when you
+    want to build your index for the first time. You can achieve that goal
+    using the <classname>FullTextSession</classname>.</para>
 
     <programlisting>FullTextSession fullTextSession = Search.createFullTextSession(session);
 Transaction tx = fullTextSession.beginTransaction();
@@ -18,15 +18,15 @@
 }
 tx.commit(); //index are written at commit time    </programlisting>
 
-    <para>For maximum efficiency, Hibernate Search batch index operations
-    which and execute them at commit time (Note: you don't need to use
+    <para>For maximum efficiency, Hibernate Search batches index operations
+    and executse them at commit time (Note: you don't need to use
     <classname>org.hibernate.Transaction</classname> in a JTA
     environment).</para>
 
     <para>If you expect to index a lot of data, you need to be careful about
     memory consumption: since all documents are kept in a queue until the
     transaction commit, you can potentially face an
-    OutOfMemoryException.</para>
+    <classname>OutOfMemoryException</classname>.</para>
 
     <para>To avoid that, you can set up the
     <literal>hibernate.search.worker.batch_size</literal> property to a
@@ -40,7 +40,7 @@
     <literal>session.index()</literal> is used). That's why a sensitive
     <literal>batch_size</literal> value is expected.</para>
 
-    <para>Other parameters which also can effect indexing time and memory
+    <para>Other parameters which also can affect indexing time and memory
     consumption are
     <literal>hibernate.search.[default|&lt;indexname&gt;].batch.merge_factor</literal>
     ,
@@ -55,6 +55,7 @@
     for index (re)initialization):</para>
 
     <programlisting>fullTextSession.setFlushMode(FlushMode.MANUAL);
+fullTextSession.setCacheMode(CacheMode.IGNORE);
 transaction = fullTextSession.beginTransaction();
 //Scrollable results will avoid loading too many objects in memory
 ScrollableResults results = fullTextSession.createCriteria( Email.class ).scroll( ScrollMode.FORWARD_ONLY );

Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/configuration.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -113,14 +113,13 @@
     <para>Each indexed entity is associated to a Lucene index (an index can be
     shared by several entities but this is not usually the case). You can
     configure the index through properties prefixed by
-    <constant>hibernate.search.</constant>
-    <replaceable>indexname</replaceable> . Default properties inherited to all
-    indexes can be defined using the prefix
-    <constant>hibernate.search.default.</constant></para>
+    <constant>hibernate.search.</constant><replaceable>indexname</replaceable>
+    . Default properties inherited to all indexes can be defined using the
+    prefix <constant>hibernate.search.default.</constant></para>
 
     <para>To define the directory provider of a given index, you use the
-    <constant>hibernate.search. <replaceable>indexname</replaceable>
-    .directory_provider </constant></para>
+    <constant>hibernate.search.<replaceable>indexname</replaceable>.directory_provider
+    </constant></para>
 
     <programlisting>hibernate.search.default.directory_provider org.hibernate.search.store.FSDirectoryProvider
 hibernate.search.default.indexBase=/usr/lucene/indexes
@@ -154,10 +153,10 @@
     <para>In some extreme cases involving huge indexes (in size), it is
     necessary to split (shard) the indexing data of a given entity type into
     several Lucene indexes. This solution is not recommended until you reach
-    significant index sizes and important index updates are slowing down. The
-    main drawback of index sharding is that searches will end up being slower
-    since more files have to be opend for a single search. In other words
-    don't do it until you have problems :)</para>
+    significant index sizes and index update time are slowing down. The main
+    drawback of index sharding is that searches will end up being slower since
+    more files have to be opend for a single search. In other words don't do
+    it until you have problems :)</para>
 
     <para>Despite this strong warning, Hibernate Search allows you to index a
     given entity type into several sub indexes. Data is sharded into the
@@ -196,7 +195,7 @@
 hibernate.search.Animal.3.indexName Animal03</programlisting>
 
     <para>This configuration uses the default id string hashing strategy and
-    shards the Animal index intp 5 subindexes. All subindexes are
+    shards the Animal index into 5 subindexes. All subindexes are
     FSDirectoryProvider instances and the directory where each subindex is
     stored is as followed:</para>
 
@@ -231,8 +230,11 @@
   <section>
     <title>Worker configuration</title>
 
-    <para>Hibernate Search works done by a worker you can configure. The
-    default (and only) worker today use transactional scoping.</para>
+    <para>It is possible to refine how Hibernate Search interacts with Lucene
+    through the worker configuration. The work can be exected to the Lucene
+    directory or sent to a JMS queue for later processing. When processed to
+    the Lucene directory, the work can be processed synchronously or
+    asynchronously to the transaction commit.</para>
 
     <para>You can define the worker configuration using the following
     properties</para>
@@ -455,12 +457,6 @@
   <section id="search-configuration-event" revision="2">
     <title>Enabling Hibernate Search and automatic indexing</title>
 
-    <para>Hibernate Search is enabled out of the box when using Hibernate
-    Annotations or Hibernate EntityManager. If, for some reason you need to
-    disable it, set <literal>hibernate.search.autoregister_listeners</literal>
-    to false. Note that there is no performance runtime when the listeners are
-    enabled while no entity is indexable.</para>
-
     <section>
       <title>Enabling Hibernate Search</title>
 
@@ -536,14 +532,15 @@
 
     <para>Hibernate Search allows you to tune the Lucene indexing performance
     by specifying a set of parameters which are passed through to underlying
-    Lucene <literal>IndexWriter</literal> as <literal>mergeFactor</literal>,
-    <literal>maxMergeDocs</literal> and <literal>maxBufferedDocs</literal>.
-    You can specify these parameters either as default values applying for all
-    indexes or on a per index basis.</para>
+    Lucene <literal>IndexWriter</literal> such as
+    <literal>mergeFactor</literal>, <literal>maxMergeDocs</literal> and
+    <literal>maxBufferedDocs</literal>. You can specify these parameters
+    either as default values applying for all indexes or on a per index
+    basis.</para>
 
     <para>There are two sets of parameters allowing for different performance
     settings depending on the use case. During indexing operations triggered
-    by database modifications: <itemizedlist>
+    by database modifications, the following ones are used: <itemizedlist>
         <listitem>
           <literal>hibernate.search.[default|&lt;indexname&gt;].transaction.merge_factor</literal>
         </listitem>
@@ -555,7 +552,10 @@
         <listitem>
           <literal>hibernate.search.[default|&lt;indexname&gt;].transaction.max_buffered_docs</literal>
         </listitem>
-      </itemizedlist> are used. The corresponding properties: <itemizedlist>
+      </itemizedlist>When indexing occurs via
+    <literal>FullTextSession.index()</literal> (see <xref
+    linkend="search-batchindex" />), the following properties are used:
+    <itemizedlist>
         <listitem>
           <literal>hibernate.search.[default|&lt;indexname&gt;].batch.merge_factor</literal>
         </listitem>
@@ -567,9 +567,7 @@
         <listitem>
           <literal>hibernate.search.[default|&lt;indexname&gt;].batch.max_buffered_docs</literal>
         </listitem>
-      </itemizedlist> are applied when indexing occurs via
-    <literal>FullTextSession.index()</literal> (see <xref
-    linkend="search-batchindex" />).</para>
+      </itemizedlist></para>
 
     <para>Unless the corresponding <literal>.batch</literal> property is
     explicitly set, the value will default to the

Modified: search/trunk/doc/reference/en/modules/getting-started.xml
===================================================================
--- search/trunk/doc/reference/en/modules/getting-started.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/getting-started.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -3,10 +3,11 @@
 <chapter id="getting-started">
   <title>Getting started</title>
 
-  <para>The following chapter will guide you through the initial steps
-  required to integrate Hibernate Search into an existing Hibernate enabled
-  application. In case you are a Hibernate new timer we recommend you start
-  <ulink url="http://hibernate.org/152.html">here</ulink>.</para>
+  <para>Welcome to Hibernate Search! The following chapter will guide you
+  through the initial steps required to integrate Hibernate Search into an
+  existing Hibernate enabled application. In case you are a Hibernate new
+  timer we recommend you start <ulink
+  url="http://hibernate.org/152.html">here</ulink>.</para>
 
   <section>
     <title>System Requirements</title>
@@ -19,8 +20,8 @@
           <row>
             <entry>Java Runtime</entry>
 
-            <entry>A JDK or JRE version <emphasis>1.5</emphasis> or greater.
-            You can download a Java Runtime for Windows/Linux/Solaris <ulink
+            <entry>A JDK or JRE version <emphasis>5</emphasis> or greater. You
+            can download a Java Runtime for Windows/Linux/Solaris <ulink
             url="http://java.sun.com/javase/downloads/"> here
             </ulink>.</entry>
           </row>
@@ -30,7 +31,7 @@
 
             <entry><literal>hibernate-search.jar</literal> and all the
             dependencies from the <literal>lib</literal> directory of the
-            Hibernate Search distribution.</entry>
+            Hibernate Search distribution, especially lucene :)</entry>
           </row>
 
           <row>
@@ -59,7 +60,7 @@
     <para>You can download all dependencies from the Hibernate <ulink
     url="http://www.hibernate.org/6.html">download site</ulink>. You can also
     verify the dependency versions against the <ulink
-    url="http://www.hibernate.org/6.html#A3"> Hibernate Compatibility
+    url="http://www.hibernate.org/6.html#A3">Hibernate Compatibility
     Matrix</ulink>.</para>
   </section>
 
@@ -71,7 +72,7 @@
     url="http://repository.jboss.com/maven2">JBoss maven repository</ulink>.
     Just add the JBoss repository url to the <emphasis>repositories</emphasis>
     section of your <filename>pom.xml</filename> or
-    <filename>settgins.xml</filename>:</para>
+    <filename>settings.xml</filename>:</para>
 
     <programlisting>
 &lt;repository&gt;
@@ -88,7 +89,7 @@
 &lt;dependency&gt;
    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
    &lt;artifactId&gt;hibernate-search&lt;/artifactId&gt;
-   &lt;version&gt;3.0.0.CR1&lt;/version&gt;
+   &lt;version&gt;3.0.0.ga&lt;/version&gt;
 &lt;/dependency&gt;
 &lt;dependency&gt;
    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
@@ -149,8 +150,8 @@
   private Integer id; 
   private String body;  
   private String summary; 
-  private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
-  private Author mainAuthor;
+  @ManyToMany private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
+  @ManyToOne private Author mainAuthor;
   private Date publicationDate;
   
   public Book() {
@@ -182,19 +183,22 @@
     indexable. By design Hibernate Search needs to store an untokenized id in
     the index to ensure index unicity for a given entity.
     <literal>@DocumentId</literal> marks the property to use for this purpose.
-    Last but not least you have to index the fields you want to make
-    searchable. In our example these fields are <literal>body</literal> and
+    Most if not all the time, the property is the database primary key. Last
+    but not least you have to index the fields you want to make searchable. In
+    our example these fields are <literal>body</literal> and
     <literal>summary</literal>. Both properties get annotated with
     <literal>@Field</literal>. The property
     <literal>index=Index.TOKENIZED</literal> will ensure that the text will be
     tokenized using the default Lucene analyzer whereas
     <literal>store=Store.NO</literal> ensures that the actual data will not be
-    stored in the index.</para>
+    stored in the index. Usually, tokenizing means chunking a sentence into
+    individual words (and potentially excluding common words like
+    <literal>a</literal>, <literal>the </literal>etc).</para>
 
     <para>These settings are sufficient for an initial test. For more details
     on entity mapping refer to <xref linkend="search-mapping-entity" />. In
     case you want to store and retrieve the indexed data in order to avoid
-    database roundtrips refer to projections in <xref
+    database roundtrips, refer to projections in <xref
     linkend="projections" /></para>
 
     <programlisting>
@@ -213,8 +217,8 @@
   
   <emphasis role="bold">@Field(index=Index.TOKENIZED, store=Store.NO)</emphasis>
   private String summary; 
-  private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
-  private Author mainAuthor;
+  @ManyToMany private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
+  @ManyToOne private Author mainAuthor;
   private Date publicationDate;
   
   public Book() {
@@ -228,10 +232,13 @@
   <section>
     <title>Indexing</title>
 
-    <para>Once you have added the above properties and annotations it is time
-    to trigger an initial batch index of your books. You can achieve this by
-    adding one of the following code examples to your code (see also <xref
-    linkend="search-batchindex" />):</para>
+    <para>Hibernate Search will index every entity persisted, updated or
+    removed through Hibernate core transparently for the application. However,
+    the data already present in your database needs to be indexed once to
+    populate the Lucene index. Once you have added the above properties and
+    annotations it is time to trigger an initial batch index of your books.
+    You can achieve this by adding one of the following code examples to your
+    code (see also <xref linkend="search-batchindex" />):</para>
 
     <para>Example using Hibernate Session:</para>
 
@@ -256,9 +263,9 @@
 } 
     </programlisting>
 
-    <para>After executing the above code there should be a Lucene index under
-    <literal>/var/lucene/indexes/example.Book</literal>. Go ahead an inspect
-    this index. It will help you to understand how Hibernate Search
+    <para>After executing the above code, you should be able to see a Lucene
+    index under <literal>/var/lucene/indexes/example.Book</literal>. Go ahead
+    an inspect this index. It will help you to understand how Hibernate Search
     works.</para>
   </section>
 
@@ -320,12 +327,12 @@
       </listitem>
 
       <listitem>
-        <para>Setting the <literal>Analyzer</literal> annotation on entity
+        <para>Setting the <literal>Analyzer</literal> annotation at the entity
         level.</para>
       </listitem>
 
       <listitem>
-        <para>Setting the <literal>Analyzer</literal> annotation on field
+        <para>Setting the <literal>Analyzer</literal> annotation at the field
         level.</para>
       </listitem>
     </itemizedlist>
@@ -354,8 +361,8 @@
   
   @Field(index=Index.TOKENIZED, store=Store.NO)
   private String summary; 
-  private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
-  private Author mainAuthor;
+  @ManyToMany private Set&lt;Author&gt; authors = new HashSet&lt;Author&gt;();
+  @ManyToOne private Author mainAuthor;
   private Date publicationDate;
   
   public Book() {
@@ -385,8 +392,8 @@
     <title>What's next</title>
 
     <para>The above paragraphs hopefully helped you getting started with
-    Hibernate Search. You should by now have a simple file system based index
-    and be able to search and retrieve a list of managed objects via Hibernate
+    Hibernate Search. You should by now have a file system based index and be
+    able to search and retrieve a list of managed objects via Hibernate
     Search. The next step is to get more familiar with the overall
     architecture ((<xref linkend="search-architecture" />)) and explore the
     basic features in more detail.</para>
@@ -394,7 +401,7 @@
     <para>Two topics which where only briefly touched in this tutorial were
     analyzer configuration (<xref linkend="analyzer" />) and field bridges
     (<xref linkend="search-mapping-bridge" />), both important features
-    required for more fain grained indexing.</para>
+    required for more fine-grained indexing.</para>
 
     <para>More advanced topics cover clustering (<xref
     linkend="jms-backend" />) and large indexes handling (<xref

Modified: search/trunk/doc/reference/en/modules/mapping.xml
===================================================================
--- search/trunk/doc/reference/en/modules/mapping.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/mapping.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -68,7 +68,7 @@
           an analyzer to process the property),
           <literal>Index.UN_TOKENISED</literal> (no analyzer pre processing),
           <literal>Index.NO_NORM</literal> (do not store the normalization
-          data).</para>
+          data). The default value is <literal>TOKENIZED</literal>.</para>
         </listitem>
       </itemizedlist>
 
@@ -171,7 +171,8 @@
       <title>Embedded and associated objects</title>
 
       <para>Associated objects as well as embedded objects can be indexed as
-      part of the root entity index.</para>
+      part of the root entity index. It is necessary if you expect to search a
+      given entity based on properties of the associated object(s).</para>
 
       <programlisting>@Entity
 @Indexed
@@ -220,7 +221,7 @@
       <para><literal>@ContainedIn</literal> is useful on embedded objects that
       are also entities (like <literal>Address</literal> in this example): it
       basically means that when an address entity is updated, the index
-      document of the associated <literal>Place</literal>(s), also have to be
+      document of the associated <literal>Place</literal>(s), also has to be
       updated.</para>
 
       <para>Let's make our example a bit more complex:</para>
@@ -405,13 +406,13 @@
 
       <para>The default analyzer class used to index the elements is
       configurable through the <literal>hibernate.search.analyzer</literal>
-      property. If none defined,
+      property. If none is defined,
       <classname>org.apache.lucene.analysis.standard.StandardAnalyzer</classname>
       is used as the default.</para>
 
       <para>You can also define the analyzer class per entity, per property
       and even per @Field (useful when multiple fields are indexed from a
-      single proeprty).</para>
+      single property).</para>
 
       <programlisting>@Entity
 @Indexed
@@ -455,12 +456,12 @@
   <section id="search-mapping-bridge">
     <title>Property/Field Bridge</title>
 
-    <para>In Lucene all index fields have to be represented as
-    Strings. For this reason all entity properties annotated with <literal>@Field</literal> 
-    have to be indexed in a String form. For
-    most of your properties, Hibernate Search does the translation job for you
-    thanks to a built-in set of bridges. In some cases, though you need a more fine
-    grain control over the translation process.</para>
+    <para>In Lucene all index fields have to be represented as Strings. For
+    this reason all entity properties annotated with <literal>@Field</literal>
+    have to be indexed in a String form. For most of your properties,
+    Hibernate Search does the translation job for you thanks to a built-in set
+    of bridges. In some cases, though you need a more fine grain control over
+    the translation process.</para>
 
     <section>
       <title>Built-in bridges</title>
@@ -469,9 +470,6 @@
       built-in bridges between a Java property type and its full text
       representation.</para>
 
-      <para><literal>Null</literal> elements are not indexed (Lucene does not
-      support null elements and it does not make much sense either)</para>
-
       <variablelist>
         <varlistentry>
           <term>null</term>
@@ -547,10 +545,10 @@
     <section>
       <title>Custom Bridge</title>
 
-      <para>It can happen that the built-in bridges of Hibernate Search do
-      not cover some of your property types, or that the String representation
-      used is not what you expect. The following paragraphs sveral solutions for this
-      problem.</para>
+      <para>It can happen that the built-in bridges of Hibernate Search do not
+      cover some of your property types, or that the String representation
+      used is not what you expect. The following paragraphs sveral solutions
+      for this problem.</para>
 
       <section>
         <title>StringBridge</title>
@@ -736,6 +734,72 @@
 
         <para></para>
       </section>
+
+      <section>
+        <title>@ClassBridge</title>
+
+        <para>It is sometimes useful to combine more than one property of a
+        given entity and index this combination in a specific way into the
+        Lucene index. The <classname>@ClassBridge</classname> and
+        <classname>@ClassBridges</classname> annotations can be defined at the
+        class level (as opposed to the property level). In this case the
+        custom field bridge implementation receives the entity instance as the
+        value parameter instead of a particular property.</para>
+
+        <programlisting>@Entity
+ at Indexed
+<emphasis role="bold">@ClassBridge</emphasis>(name="branchnetwork",
+             index=Index.TOKENIZED,
+             store=Store.YES,
+             impl = <emphasis role="bold">CatFieldsClassBridge.class</emphasis>,
+             params = @Parameter( name="sepChar", value=" " ) )
+public class Department {
+    private int id;
+    private String network;
+    private String branchHead;
+    private String branch;
+    private Integer maxEmployees;
+    ...
+}
+
+public class CatFieldsClassBridge implements FieldBridge, ParameterizedBridge {
+
+    private String sepChar;
+
+    public void setParameterValues(Map parameters) {
+        this.sepChar = (String) parameters.get( "sepChar" );
+    }
+
+    public void set(String name, 
+                Object value, //the department instance (entity) in this case
+                Document document, //the Lucene document 
+                Field.Store store, Field.Index index, Float boost) {
+        // In this particular class the name of the new field was passed
+        // from the name field of the ClassBridge Annotation. This is not
+        // a requirement. It just works that way in this instance. The
+        // actual name could be supplied by hard coding it below.
+        Department dep = (Department) value;
+        String fieldValue1 = dep.getBranch();
+        if ( fieldValue1 == null ) {
+            fieldValue1 = "";
+        }
+        String fieldValue2 = dep.getNetwork();
+        if ( fieldValue2 == null ) {
+            fieldValue2 = "";
+        }
+        String fieldValue = fieldValue1 + sepChar + fieldValue2;
+        Field field = new Field( name, fieldValue, store, index );
+        if ( boost != null ) field.setBoost( boost );
+        document.add( field );
+    }
+}</programlisting>
+
+        <para>In this example, the particular
+        <classname>CatFieldsClassBridge</classname> is applied to the
+        <literal>department</literal> instance, the field bridge then
+        concatenate both branch and network and index the
+        concatenation.</para>
+      </section>
     </section>
   </section>
 </chapter>
\ No newline at end of file

Modified: search/trunk/doc/reference/en/modules/query.xml
===================================================================
--- search/trunk/doc/reference/en/modules/query.xml	2007-09-21 16:34:06 UTC (rev 14020)
+++ search/trunk/doc/reference/en/modules/query.xml	2007-09-23 20:17:51 UTC (rev 14021)
@@ -11,7 +11,7 @@
 
   <para>To access the <productname>Hibernate Search</productname> querying
   facilities, you have to use an Hibernate
-  <classname>FullTextSession</classname> . A Search Session wrap an regular
+  <classname>FullTextSession</classname> . A Search Session wraps a regular
   <classname>org.hibernate.Session</classname> to provide query and indexing
   capabilities.</para>
 
@@ -74,7 +74,7 @@
     </section>
 
     <section>
-      <title>Building an Hibernate Search query</title>
+      <title>Building a Hibernate Search query</title>
 
       <section>
         <title>Generality</title>
@@ -280,7 +280,7 @@
       Search has to process all Lucene Hits elements (within the pagination)
       when using <methodname>list()</methodname> ,
       <methodname>uniqueResult()</methodname> and
-      <methodname>iterate()</methodname>. </para>
+      <methodname>iterate()</methodname>.</para>
 
       <para>If you wish to minimize Lucene document loading,
       <methodname>scroll()</methodname> is more appropriate. Don't forget to
@@ -289,7 +289,7 @@
       <methodname>scroll</methodname> but wish to load objects in batch, you
       can use <methodname>query.setFetchSize()</methodname>: When an object is
       accessed, and if not already loaded, Hibernate Search will load the next
-      <literal>fetchSize</literal> objects in one pass. </para>
+      <literal>fetchSize</literal> objects in one pass.</para>
 
       <para>Pagination is a preferred method over scrolling though.</para>
     </section>
@@ -345,7 +345,7 @@
     <para>Apache Lucene has a powerful feature that allows to filters results
     from a query according to a custom filtering process. This is a very
     powerful way to apply some data restrictions after a query, especially
-    since filters can be cached and reused. Some interesting usecase
+    since filters can be cached and reused. Some interesting usecases
     are:</para>
 
     <itemizedlist>
@@ -413,11 +413,12 @@
     score is 5. The filters must have a no-arg constructor when referenced in
     a <literal>FulltextFilterDef.impl</literal>.</para>
 
-    <para>The cache flag defaulted to true, tells Hibernate Search to search
-    the filter in its internal cache and reuse it if found.</para>
+    <para>The <literal>cache</literal> flag, defaulted to
+    <literal>true</literal>, tells Hibernate Search to search the filter in
+    its internal cache and reuses it if found.</para>
 
     <para>Note that, usually, filter using the
-    <classname>IndexReader</classname> are usually wrapped in a Lucene
+    <classname>IndexReader</classname> are wrapped in a Lucene
     <classname>CachingWrapperFilter</classname> to benefit from some caching
     speed improvement. If your Filter creation requires additional steps or if
     the filter you are willing to use does not have a no-arg constructor, you
@@ -515,7 +516,7 @@
       </listitem>
 
       <listitem>
-        <para>the Filter BitSet is expenseve to consume (compared to the time
+        <para>the Filter BitSet is expensive to compute (compared to the time
         spent to execute the query)</para>
       </listitem>
     </itemizedlist>




More information about the hibernate-commits mailing list