From hibernate-commits at lists.jboss.org Sun Sep 23 16:17:52 2007 Content-Type: multipart/mixed; boundary="===============8461047618865960118==" MIME-Version: 1.0 From: hibernate-commits at lists.jboss.org To: hibernate-commits at lists.jboss.org Subject: [hibernate-commits] Hibernate SVN: r14021 - in search/trunk/doc/reference/en: modules and 1 other directory. Date: Sun, 23 Sep 2007 16:17:51 -0400 Message-ID: --===============8461047618865960118== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- search/trunk/doc/reference/en/master.xml 2007-09-21 16:34:06 UTC (rev 1= 4020) +++ search/trunk/doc/reference/en/master.xml 2007-09-23 20:17:51 UTC (rev 1= 4021) @@ -19,7 +19,7 @@ = Reference Guide = - 3.0.0.CR1 + 3.0.0.GA = Modified: search/trunk/doc/reference/en/modules/architecture.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 @@ Architecture +
Overview - = - Hibernate Search consists of an indexing and an index search - engine. Both are backed by Apache Lucene. = - 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 ). - + Hibernate Search consists of an indexing and an index search eng= ine. + Both are backed by Apache Lucene. = - To interact with Apache Lucene indexes, Hibernate Search has the - notion of DirectoryProviders. A directory provider - will manage a given Lucene Directory type. You can - configure directory providers to adjust the directory target - (see ). + When an entity is inserted, updated or removed in/from the datab= ase, + Hibernate Search keeps track of this event (through the Hibernate event + system) and schedules an index update. All the index updates are handl= ed + for you without you having to use the Apache Lucene APIs (see ). = - 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 org.hibernate.Query - or javax.persistence.Query APIs exactly the way a - HQL, JPA-QL or native queries would do. + To interact with Apache Lucene indexes, Hibernate Search has the + notion of DirectoryProviders. A directory provi= der + will manage a given Lucene Directory type. You = can + configure directory providers to adjust the directory target (see ). = - To be more efficient, Hibernate Search batches the write interacti= ons - with the Lucene index. There is currently two types of batching depending - on the expected scope. + Hibernate Search can also use the Lucene index to search an enti= ty + 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 Sessio= n is + built on top of the Hibernate Session. The application code use the + unified org.hibernate.Query or + javax.persistence.Query APIs exactly the way a = HQL, + JPA-QL or native queries would do. = - 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. + 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. = - 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: + Outside a transaction, the index update operation is executed ri= ght + after the actual database operation. This scope is really a no scoping + setup and no batching is performed. = - - - Performance: Lucene indexing works better when operation are - executed in batch. - + 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: = - - 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. + + + Performance: Lucene indexing works better when operation are + executed in batch. + = - - 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. - - - + + 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. = - You can think of those two scopes (no scope vs transactional) as t= he - equivalent of the (infamous) autocommit vs transactional behavior. From a - performance perspective, the in transaction mode is - recommended. The scoping choice is made transparently: Hibernate Search - detects the presence of a transaction and adjust the scoping. + + 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. + + + = - Hibernate Search works perfectly fine in the Hibernate / - EntityManager long conversation pattern aka. atomic conversation. + You can think of those two scopes (no scope vs transactional) as= the + equivalent of the (infamous) autocommit vs transactional behavior. Fro= m a + performance perspective, the in transaction mode = is + recommended. The scoping choice is made transparently: Hibernate Search + detects the presence of a transaction and adjust the scoping. = - Depending on user demand, additional scoping will be considered, t= he - pluggability mechanism being already in place. + + Hibernate Search works perfectly fine in the Hibernate / EntityManag= er long conversation pattern aka. atomic conversation. + + + + Depending on user demand, additional scoping will be considered, the= pluggability mechanism being already in place. +
=
@@ -90,8 +92,8 @@ In this mode, all index update operations applied on a given n= ode (JVM) will be executed to the Lucene directories (through the direct= ory providers) by the same node. This mode is typically used in non - clustered environment or in clustered environments where the directo= ry store is - shared. + clustered environment or in clustered environments where the directo= ry + store is shared. = @@ -123,8 +125,8 @@ basis to the slave copies. This is known as the master / slaves patt= ern. The master is the sole responsible for updating the Lucene index. The slaves can accept read as well as write operations. However, they on= ly - process the read operation on their local index copy and delegate th= e update = - operations to the master. + process the read operation on their local index copy and delegate the + update operations to the master. = @@ -145,9 +147,8 @@
= Hibernate Search is an extensible architecture. While not yet pa= rt - of the public API, plugging a third party back end is possible. Feel - free to drop ideas to - hibernate-dev(a)lists.jboss.org. + of the public API, plugging a third party back end is possible. Feel f= ree + to drop ideas to hibernate-dev(a)lists.jboss.org. =
@@ -178,9 +179,9 @@ small overhead is introduced to deal with thread management. = It is recommended to use synchronous execution first and evalu= ate - asynchronous execution if performance problems occur and after havin= g set up a - proper benchmark (ie not a lonely cowboy hitting the system in a - completely unrealistic way). + 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).
= @@ -190,7 +191,8 @@ When executing a query, Hibernate Search interacts with the Apac= he Lucene indexes through a reader strategy. chosing a reader strategy wi= ll depend on the profile of the application (frequent updates, read mostl= y, - asynchronous index update etc). See also + asynchronous index update etc). See also =
Shared Modified: search/trunk/doc/reference/en/modules/batchindex.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- search/trunk/doc/reference/en/modules/batchindex.xml 2007-09-21 16:34:0= 6 UTC (rev 14020) +++ search/trunk/doc/reference/en/modules/batchindex.xml 2007-09-23 20:17:5= 1 UTC (rev 14021) @@ -6,10 +6,10 @@
Indexing = - 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 usi= ng - the FullTextSession . + 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 FullTextSession. = FullTextSession fullTextSession =3D Search.createFullT= extSession(session); Transaction tx =3D fullTextSession.beginTransaction(); @@ -18,15 +18,15 @@ } tx.commit(); //index are written at commit time = - For maximum efficiency, Hibernate Search batch index operations - which and execute them at commit time (Note: you don't need to use + For maximum efficiency, Hibernate Search batches index operations + and executse them at commit time (Note: you don't need to use org.hibernate.Transaction in a JTA environment). = If you expect to index a lot of data, you need to be careful abo= ut memory consumption: since all documents are kept in a queue until the transaction commit, you can potentially face an - OutOfMemoryException. + OutOfMemoryException. = To avoid that, you can set up the hibernate.search.worker.batch_size property to a @@ -40,7 +40,7 @@ session.index() is used). That's why a sensitive batch_size value is expected. = - Other parameters which also can effect indexing time and memory + Other parameters which also can affect indexing time and memory consumption are hibernate.search.[default|<indexname>].batch.merge_fact= or , @@ -55,6 +55,7 @@ for index (re)initialization): = fullTextSession.setFlushMode(FlushMode.MANUAL); +fullTextSession.setCacheMode(CacheMode.IGNORE); transaction =3D fullTextSession.beginTransaction(); //Scrollable results will avoid loading too many objects in memory ScrollableResults results =3D fullTextSession.createCriteria( Email.class = ).scroll( ScrollMode.FORWARD_ONLY ); Modified: search/trunk/doc/reference/en/modules/configuration.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- search/trunk/doc/reference/en/modules/configuration.xml 2007-09-21 16:3= 4:06 UTC (rev 14020) +++ search/trunk/doc/reference/en/modules/configuration.xml 2007-09-23 20:1= 7:51 UTC (rev 14021) @@ -113,14 +113,13 @@ Each indexed entity is associated to a Lucene index (an index ca= n be shared by several entities but this is not usually the case). You can configure the index through properties prefixed by - hibernate.search. - indexname . Default properties inherited to= all - indexes can be defined using the prefix - hibernate.search.default. + hibernate.search.indexname + . Default properties inherited to all indexes can be defined using the + prefix hibernate.search.default. = To define the directory provider of a given index, you use the - hibernate.search. indexname - .directory_provider + hibernate.search.indexname.direct= ory_provider + = hibernate.search.default.directory_provider org.hibern= ate.search.store.FSDirectoryProvider hibernate.search.default.indexBase=3D/usr/lucene/indexes @@ -154,10 +153,10 @@ In some extreme cases involving huge indexes (in size), it is necessary to split (shard) the indexing data of a given entity type in= to several Lucene indexes. This solution is not recommended until you rea= ch - significant index sizes and important index updates are slowing down. = The - main drawback of index sharding is that searches will end up being slo= wer - since more files have to be opend for a single search. In other words - don't do it until you have problems :) + significant index sizes and index update time are slowing down. The ma= in + drawback of index sharding is that searches will end up being slower s= ince + more files have to be opend for a single search. In other words don't = do + it until you have problems :) = Despite this strong warning, Hibernate Search allows you to inde= x a given entity type into several sub indexes. Data is sharded into the @@ -196,7 +195,7 @@ hibernate.search.Animal.3.indexName Animal03 = This configuration uses the default id string hashing strategy a= nd - 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: = @@ -231,8 +230,11 @@
Worker configuration = - Hibernate Search works done by a worker you can configure. The - default (and only) worker today use transactional scoping. + It is possible to refine how Hibernate Search interacts with Luc= ene + 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. = You can define the worker configuration using the following properties @@ -455,12 +457,6 @@
Enabling Hibernate Search and automatic indexing = - 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 hibernate.search.autoregister_listeners - to false. Note that there is no performance runtime when the listeners= are - enabled while no entity is indexable. -
Enabling Hibernate Search = @@ -536,14 +532,15 @@ = Hibernate Search allows you to tune the Lucene indexing performa= nce by specifying a set of parameters which are passed through to underlyi= ng - Lucene IndexWriter as mergeFactor, - maxMergeDocs and maxBufferedDocs. - You can specify these parameters either as default values applying for= all - indexes or on a per index basis. + Lucene IndexWriter such as + mergeFactor, maxMergeDocs and + maxBufferedDocs. You can specify these parameters + either as default values applying for all indexes or on a per index + basis. = There are two sets of parameters allowing for different performa= nce settings depending on the use case. During indexing operations trigger= ed - by database modifications: + by database modifications, the following ones are used: hibernate.search.[default|<indexname>].transactio= n.merge_factor @@ -555,7 +552,10 @@ hibernate.search.[default|<indexname>].transactio= n.max_buffered_docs - are used. The corresponding properties: + When indexing occurs via + FullTextSession.index() (see ), the following properties are used: + hibernate.search.[default|<indexname>].batch.merg= e_factor @@ -567,9 +567,7 @@ hibernate.search.[default|<indexname>].batch.max_= buffered_docs - are applied when indexing occurs via - FullTextSession.index() (see ). + = Unless the corresponding .batch property is explicitly set, the value will default to the Modified: search/trunk/doc/reference/en/modules/getting-started.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 @@ Getting started = - 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 - here. + 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 here. =
System Requirements @@ -19,8 +20,8 @@ Java Runtime = - A JDK or JRE version 1.5 or greate= r. - You can download a Java Runtime for Windows/Linux/Solaris A JDK or JRE version 5 or greater.= You + can download a Java Runtime for Windows/Linux/Solaris here . @@ -30,7 +31,7 @@ = hibernate-search.jar and all the dependencies from the lib directory of the - Hibernate Search distribution. + Hibernate Search distribution, especially lucene :) = @@ -59,7 +60,7 @@ You can download all dependencies from the Hibernate download site. You can= also verify the dependency versions against the Hibernate Compatibility + url=3D"http://www.hibernate.org/6.html#A3">Hibernate Compatibility Matrix.
= @@ -71,7 +72,7 @@ url=3D"http://repository.jboss.com/maven2">JBoss maven repository. Just add the JBoss repository url to the repositories section of your pom.xml or - settgins.xml:
+ settings.xml: = <repository> @@ -88,7 +89,7 @@ <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search</artifactId> - <version>3.0.0.CR1</version> + <version>3.0.0.ga</version> </dependency> <dependency> <groupId>org.hibernate</groupId> @@ -149,8 +150,8 @@ private Integer id; = private String body; = private String summary; = - private Set<Author> authors =3D new HashSet<Author>(); - private Author mainAuthor; + @ManyToMany private Set<Author> authors =3D new HashSet<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. @DocumentId marks the property to use for this purp= ose. - Last but not least you have to index the fields you want to make - searchable. In our example these fields are body and + Most if not all the time, the property is the database primary key. La= st + but not least you have to index the fields you want to make searchable= . In + our example these fields are body and summary. Both properties get annotated with @Field. The property index=3DIndex.TOKENIZED will ensure that the text w= ill be tokenized using the default Lucene analyzer whereas store=3DStore.NO ensures that the actual data will = not be - stored in the index. + stored in the index. Usually, tokenizing means chunking a sentence into + individual words (and potentially excluding common words like + a, the etc). = These settings are sufficient for an initial test. For more deta= ils on entity mapping refer to .= In case you want to store and retrieve the indexed data in order to avoid - database roundtrips refer to projections in = @@ -213,8 +217,8 @@ = @Field(index=3DIndex.TOKENIZED, store=3DStore.NO= ) private String summary; = - private Set<Author> authors =3D new HashSet<Author>(); - private Author mainAuthor; + @ManyToMany private Set<Author> authors =3D new HashSet<Author&= gt;(); + @ManyToOne private Author mainAuthor; private Date publicationDate; = public Book() { @@ -228,10 +232,13 @@
Indexing = - Once you have added the above properties and annotations it is t= ime - 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 ): + Hibernate Search will index every entity persisted, updated or + removed through Hibernate core transparently for the application. Howe= ver, + 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 y= our + code (see also ): = Example using Hibernate Session: = @@ -256,9 +263,9 @@ } = = - After executing the above code there should be a Lucene index un= der - /var/lucene/indexes/example.Book. Go ahead an inspe= ct - this index. It will help you to understand how Hibernate Search + After executing the above code, you should be able to see a Luce= ne + index under /var/lucene/indexes/example.Book. Go ah= ead + an inspect this index. It will help you to understand how Hibernate Se= arch works.
= @@ -320,12 +327,12 @@ = - Setting the Analyzer annotation on entity + Setting the Analyzer annotation at the en= tity level. = - Setting the Analyzer annotation on field + Setting the Analyzer annotation at the fi= eld level. @@ -354,8 +361,8 @@ = @Field(index=3DIndex.TOKENIZED, store=3DStore.NO) private String summary; = - private Set<Author> authors =3D new HashSet<Author>(); - private Author mainAuthor; + @ManyToMany private Set<Author> authors =3D new HashSet<Author&= gt;(); + @ManyToOne private Author mainAuthor; private Date publicationDate; = public Book() { @@ -385,8 +392,8 @@ What's next = The above paragraphs hopefully helped you getting started with - Hibernate Search. You should by now have a simple file system based in= dex - and be able to search and retrieve a list of managed objects via Hiber= nate + 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 (()) and explore = the basic features in more detail. @@ -394,7 +401,7 @@ Two topics which where only briefly touched in this tutorial were analyzer configuration () and field bridg= es (), both important features - required for more fain grained indexing. + required for more fine-grained indexing. = More advanced topics cover clustering () and large indexes handling (Index.UN_TOKENISED (no analyzer pre processin= g), Index.NO_NORM (do not store the normalization - data). + data). The default value is TOKENIZED. = @@ -171,7 +171,8 @@ Embedded and associated objects = Associated objects as well as embedded objects can be indexed = as - part of the root entity index. + part of the root entity index. It is necessary if you expect to sear= ch a + given entity based on properties of the associated object(s). = @Entity @Indexed @@ -220,7 +221,7 @@ @ContainedIn is useful on embedded objects = that are also entities (like Address in this example):= it basically means that when an address entity is updated, the index - document of the associated Place(s), also have to= be + document of the associated Place(s), also has to = be updated. = Let's make our example a bit more complex: @@ -405,13 +406,13 @@ = The default analyzer class used to index the elements is configurable through the hibernate.search.analyzer - property. If none defined, + property. If none is defined, org.apache.lucene.analysis.standard.StandardAnalyzer is used as the default. = 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). + single property). = @Entity @Indexed @@ -455,12 +456,12 @@
Property/Field Bridge = - In Lucene all index fields have to be represented as - Strings. For this reason all entity properties annotated with @Field = - 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. + In Lucene all index fields have to be represented as Strings. For + this reason all entity properties annotated with @Field + 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 o= ver + the translation process. =
Built-in bridges @@ -469,9 +470,6 @@ built-in bridges between a Java property type and its full text representation. = - Null elements are not indexed (Lucene does = not - support null elements and it does not make much sense either) - null @@ -547,10 +545,10 @@
Custom Bridge = - It can happen that the built-in bridges of Hibernate Search do - not cover some of your property types, or that the String representa= tion - used is not what you expect. The following paragraphs sveral solutio= ns for this - problem. + 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 solutio= ns + for this problem. =
StringBridge @@ -736,6 +734,72 @@ =
+ +
+ @ClassBridge + + 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 @ClassBridge and + @ClassBridges 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. + + @Entity +(a)Indexed +@ClassBridge(name=3D"branchnetwork", + index=3DIndex.TOKENIZED, + store=3DStore.YES, + impl =3D CatFieldsClassBridge.class, + params =3D @Parameter( name=3D"sepChar", value=3D" " ) ) +public class Department { + private int id; + private String network; + private String branchHead; + private String branch; + private Integer maxEmployees; + ... +} + +public class CatFieldsClassBridge implements FieldBridge, ParameterizedBri= dge { + + private String sepChar; + + public void setParameterValues(Map parameters) { + this.sepChar =3D (String) parameters.get( "sepChar" ); + } + + public void set(String name, = + Object value, //the department instance (entity) in this c= ase + 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 =3D (Department) value; + String fieldValue1 =3D dep.getBranch(); + if ( fieldValue1 =3D=3D null ) { + fieldValue1 =3D ""; + } + String fieldValue2 =3D dep.getNetwork(); + if ( fieldValue2 =3D=3D null ) { + fieldValue2 =3D ""; + } + String fieldValue =3D fieldValue1 + sepChar + fieldValue2; + Field field =3D new Field( name, fieldValue, store, index ); + if ( boost !=3D null ) field.setBoost( boost ); + document.add( field ); + } +} + + In this example, the particular + CatFieldsClassBridge is applied to the + department instance, the field bridge then + concatenate both branch and network and index the + concatenation. +
\ No newline at end of file Modified: search/trunk/doc/reference/en/modules/query.xml =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 @@ = To access the Hibernate Search querying facilities, you have to use an Hibernate - FullTextSession . A Search Session wrap an regular + FullTextSession . A Search Session wraps a regular org.hibernate.Session to provide query and indexi= ng capabilities. = @@ -74,7 +74,7 @@
=
- Building an Hibernate Search query + Building a Hibernate Search query =
Generality @@ -280,7 +280,7 @@ Search has to process all Lucene Hits elements (within the paginatio= n) when using list() , uniqueResult() and - iterate(). + iterate(). = If you wish to minimize Lucene document loading, scroll() is more appropriate. Don't forget = to @@ -289,7 +289,7 @@ scroll but wish to load objects in batch, y= ou can use query.setFetchSize(): When an objec= t is accessed, and if not already loaded, Hibernate Search will load the = next - fetchSize objects in one pass. + fetchSize objects in one pass. = Pagination is a preferred method over scrolling though.
@@ -345,7 +345,7 @@ Apache Lucene has a powerful feature that allows to filters resu= lts 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: = @@ -413,11 +413,12 @@ score is 5. The filters must have a no-arg constructor when referenced= in a FulltextFilterDef.impl. = - The cache flag defaulted to true, tells Hibernate Search to sear= ch - the filter in its internal cache and reuse it if found. + The cache flag, defaulted to + true, tells Hibernate Search to search the filter in + its internal cache and reuses it if found. = Note that, usually, filter using the - IndexReader are usually wrapped in a Lucene + IndexReader are wrapped in a Lucene CachingWrapperFilter to benefit from some cachi= ng speed improvement. If your Filter creation requires additional steps o= r if the filter you are willing to use does not have a no-arg constructor, = you @@ -515,7 +516,7 @@ = - the Filter BitSet is expenseve to consume (compared to the t= ime + the Filter BitSet is expensive to compute (compared to the t= ime spent to execute the query) --===============8461047618865960118==--