[HSearch] Faceting feedback
by Hardy Ferentschik
Hi,
I thought it would be great to get some feedback on my faceting work.
You can see the latest on my Search fork -
https://github.com/hferentschik/hibernate-search/commits/HSEARCH-667
Technically I decided to use a simple custom Collector. I abandoned the
idea for using bobo browse, since it did
not really seem to fit our architecture and I am not sure how well
maintained the code is.
Within the custom Collector I am using Lucene's FieldCache to cache and
collect the count values during facting
(as a reminder, faceting for example means that I am searching for all
cars or a certain make, but then also want
to group the matching cars into their cubic capacity. See also -
http://en.wikipedia.org/wiki/Faceted_search)
Using the FieldCache is quite memory costly, but there are other ways to
implement the faceting itself.
At the moment I am mostly interested in the feedback around the public
API. The public classes can be found in
the package org.hibernate.search.query.facet -
https://github.com/hferentschik/hibernate-search/tree/3a9877e2bbc47a8bd6e...
The idea is to write a fulltext query as usual and then add/enable a facet:
FacetRequest request = new SimpleFacetRequest( indexFieldName,
FacetSortOrder.COUNT_DESC, false );
TermQuery term = new TermQuery( new Term( "make", "honda" ) );
FullTextQuery query = fullTextSession.createFullTextQuery( term, Car.class
);
query.enableQueryFacet( "foo", request );
Then you run the query. This will enable the facet collector and after the
query executed you get access to a map
which maps FacetResults to the facet name. Each FacetResult contains a
list of Facets which contain the actually
field values and counts:
Map<String, FacetResult> results = query.getFacetResults();
FacetResult facetResult = results.get( "foo" );
List<Facet> facetList = facetResult.getFacets();
assertEquals( "Wrong facet count for facet ", 100, facetList.get( 0
).getCount() );
More actual tests can be found here -
https://github.com/hferentschik/hibernate-search/tree/3a9877e2bbc47a8bd6e...
At the moment you are able to facet on simple (string) based values or on
number ranges (eg price ranges 0 - 100, ...). For that I have created
subclasses of
FacetRequest - SimpleFacetRequest and RangeFacetRequest (a
DateRangeFacetRequest might be interesting as well)
Some concrete questions:
* Atm, I am only exposing a programmatic API for creating FacetRequests. I
guess we want to have annotations for this as well, right?
Would we keep the programmatic configuration as a public API?
* I made the FacetRequest classes immutable atm, but this way I have a
multitude of constructors catering for a whole range of parameters
(sort order, include zero counts, ...). Any opinions around immutable
objects vs objects with setters for configuring options after creation.
If course I am interested in any other feedback as well.
--Hardy
13 years, 8 months
HV - Follow-Up: meta data API for method constraints
by Gunnar Morling
Hi,
I pretty much finished the implementation of the meta data API related to
method level constraints for Hibernate Validator (see
https://github.com/gunnarmorling/hibernate-validator/commits/HV-371). The
implementation conforms with what we currently discussed, but right now I'm
wondering whether exposing java.lang.reflect.Method on the API is actually a
good idea. I see two issues:
* Retrieving method objects via the reflection APIs is somewhat nasty, in
particular it requires to handle a checked NoSuchMethodException:
try {
Method bar = Foo.class.getDeclaredMethod( "bar", String.class );
}
catch(Exception e) {
throw new RuntimeException(e);
}
* The handling in inheritance hierarchies with overridden/implemented
methods can be confusing to users not overly familiar with the reflection
API. In particular there are different method objects for a base method and
its implementation/overriding methods. This can be irritating when invoking
MethodDescriptor#getMethod() for instance.
Therefore I would be interested in feedback on the following change:
public interface TypeDescriptor extends ElementDescriptor {
MethodDescriptor getConstraintsForMethod(String name, Class<?>...
parameterTypes);
//instead of MethodDescriptor getConstraintsForMethod(Method method);
...
}
public interface MethodDescriptor extends ElementDescriptor {
String getName();
List<Class<?>> parameterTypes();
//instead of Method getMethod()
...
}
WDYT?
Thanks, Gunnar
13 years, 8 months
Re: [hibernate-dev] hibernate-dev Digest, Vol 56, Issue 20
by Marc Schipperheyn
I have a lot of experience with Bobo Browse. The code is well maintained and
performs well.
I don't have time to download and implement code examples, but if you have
working examples up somewhere, I'd be happy to take a look.
Vriendelijke groet,
Marc
On Mon, Feb 28, 2011 at 6:00 PM, <hibernate-dev-request(a)lists.jboss.org>wrote:
> Send hibernate-dev mailing list submissions to
> hibernate-dev(a)lists.jboss.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> or, via email, send a message with subject or body 'help' to
> hibernate-dev-request(a)lists.jboss.org
>
> You can reach the person managing the list at
> hibernate-dev-owner(a)lists.jboss.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of hibernate-dev digest..."
>
>
> Today's Topics:
>
> 1. [HSearch] Faceting feedback (Hardy Ferentschik)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Mon, 28 Feb 2011 16:13:43 +0100
> From: "Hardy Ferentschik" <hibernate(a)ferentschik.de>
> Subject: [hibernate-dev] [HSearch] Faceting feedback
> To: "hibernate-dev(a)lists.jboss.org" <hibernate-dev(a)lists.jboss.org>
> Message-ID: <op.vrmck5ewqxbac6(a)sarmakand.lan>
> Content-Type: text/plain; charset=iso-8859-15; format=flowed;
> delsp=yes
>
>
> Hi,
>
> I thought it would be great to get some feedback on my faceting work.
> You can see the latest on my Search fork -
> https://github.com/hferentschik/hibernate-search/commits/HSEARCH-667
>
> Technically I decided to use a simple custom Collector. I abandoned the
> idea for using bobo browse, since it did
> not really seem to fit our architecture and I am not sure how well
> maintained the code is.
> Within the custom Collector I am using Lucene's FieldCache to cache and
> collect the count values during facting
> (as a reminder, faceting for example means that I am searching for all
> cars or a certain make, but then also want
> to group the matching cars into their cubic capacity. See also -
> http://en.wikipedia.org/wiki/Faceted_search)
> Using the FieldCache is quite memory costly, but there are other ways to
> implement the faceting itself.
>
> At the moment I am mostly interested in the feedback around the public
> API. The public classes can be found in
> the package org.hibernate.search.query.facet -
>
> https://github.com/hferentschik/hibernate-search/tree/3a9877e2bbc47a8bd6e...
>
> The idea is to write a fulltext query as usual and then add/enable a facet:
>
> FacetRequest request = new SimpleFacetRequest( indexFieldName,
> FacetSortOrder.COUNT_DESC, false );
> TermQuery term = new TermQuery( new Term( "make", "honda" ) );
> FullTextQuery query = fullTextSession.createFullTextQuery( term, Car.class
> );
> query.enableQueryFacet( "foo", request );
>
> Then you run the query. This will enable the facet collector and after the
> query executed you get access to a map
> which maps FacetResults to the facet name. Each FacetResult contains a
> list of Facets which contain the actually
> field values and counts:
>
> Map<String, FacetResult> results = query.getFacetResults();
> FacetResult facetResult = results.get( "foo" );
> List<Facet> facetList = facetResult.getFacets();
> assertEquals( "Wrong facet count for facet ", 100, facetList.get( 0
> ).getCount() );
>
> More actual tests can be found here -
>
> https://github.com/hferentschik/hibernate-search/tree/3a9877e2bbc47a8bd6e...
>
> At the moment you are able to facet on simple (string) based values or on
> number ranges (eg price ranges 0 - 100, ...). For that I have created
> subclasses of
> FacetRequest - SimpleFacetRequest and RangeFacetRequest (a
> DateRangeFacetRequest might be interesting as well)
>
> Some concrete questions:
> * Atm, I am only exposing a programmatic API for creating FacetRequests. I
> guess we want to have annotations for this as well, right?
> Would we keep the programmatic configuration as a public API?
> * I made the FacetRequest classes immutable atm, but this way I have a
> multitude of constructors catering for a whole range of parameters
> (sort order, include zero counts, ...). Any opinions around immutable
> objects vs objects with setters for configuring options after creation.
>
> If course I am interested in any other feedback as well.
>
> --Hardy
>
>
>
>
>
>
> ------------------------------
>
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>
> End of hibernate-dev Digest, Vol 56, Issue 20
> *********************************************
>
13 years, 8 months
[HSEARCH] Extract core of HSEARCH query engine to be independent of Hibernate Core.
by Emmanuel Bernard
In the last two days, I've worked on extracting the Hibernate Search specific knowledge of the query engine.
The goals are:
- let it be reused by Infinispan and other object sources
- isolate Hibernate Search from Core (longer goal
Here is the branch
https://github.com/emmanuelbernard/hibernate-search/commits/HSEARCH-687
and the commit
https://github.com/emmanuelbernard/hibernate-search/commit/bd56fee00464f9...
This is super early design but Sanne can you check it out to see if it would fit Infinispan's Search module. Check FullTextQueryImpl and ScrollableResultsetImpl for examples on how to use the SPI.
Still TODO
- Move DocumentExtractor and EntityInfo to query.engine?
- Expose a different object than DocumentExtractor (it hosts first/max and searcher for ScrollableRS which is not really correct)
- Make EntityInfo presentable
- Isolate TimeoutManager?
- Make Loader hierarchy depend on HSQuery?
- Refactor some code out of Loader implementations? At first sight, it's not necessary
- accept the fact that SearchFactoryImplementor becomes a SPI?
- create a factory for HSQuery from SearchFactoryImplementor and make HSQuery an interface
- more interfaces (EntityInfo, DocumentExtractor)?
The usage is still complex especially TimeoutManager but it's a lot better than what we had :)
13 years, 9 months
Spring Cache Abstraction
by Marc Schipperheyn
It would be interesting to have the Hibernate team comment/blog on the new
Spring Cache Abstraction functionality and how it relates to Hibernate
managed entities. Perhaps some strategies, etc. It's very attractive to just
cache entities in stead of caching entity values with the second level
cache.
13 years, 9 months
[Fwd: Re: UserType.nullSafeSet() and nullSafeGet() in H4]
by Gail Badner
The biggest change is in UserType. In the 3.6 branch (i.e., 3.6.2 and
later 3.6.x releases) , the following UserType methods will be deprecated:
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
public void nullSafeSet(PreparedStatement st, Object value, int index)
A non-deprecated alternative cannot be provided in 3.6.x, because doing
so would break implementations of UserType.
In master (H4), these deprecated methods will be replaced by:
public Object nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
public void nullSafeSet(PreparedStatement st, Object value, int
index, SessionImplementor session)
This change in master will be a breaking change that will be documented
in the H4 migration guide.
Also in master, I will be removing the nullSafeGet/nullSafeSet/get/set
methods from SingleColumnType and AbstractSingleColumnStandardBasicType
that were deprecated in 3.6
When I make these changes, I will make sure that any UserTypes defined
in master are intact.
Please let me know if there would be a problem making these changes to
master. Unless I hear otherwise, I plan to make these changes on Friday.
Cheers,
Gail
-------- Original Message --------
Subject: Re: [hibernate-dev] UserType.nullSafeSet() and nullSafeGet()
in H4
Date: Fri, 18 Feb 2011 16:50:21 -0600
From: Steve Ebersole <steve(a)hibernate.org>
Organization: http://hibernate.org
To: Gail Badner <gbadner(a)redhat.com>
References: <4D5DDBB8.6050801(a)redhat.com>
<AANLkTin+bnBhue8k-nrxuVmw1fw3h0Qe4JxuZWG813j2(a)mail.gmail.com>
<4D5EC0CC.8030709(a)redhat.com>
Yes stuff like this should always be disucssed in open (mailing list or dev
irc). See inline...
On Friday, February 18, 2011, at 12:56 pm, Gail Badner wrote:
> I also plan to do the following in master:
> 1) remove the following from SingleColumnType in master
> (already deprecated in 3.6.1):
> public T nullSafeGet(ResultSet rs, String name)
> public Object get(ResultSet rs, String name)
> public void nullSafeSet(PreparedStatement st, T value, int index)
> public void set(PreparedStatement st, T value, int index)
OK...
> 2) remove the following from AbstractSingleColumnStandardBasicType in
> master
> (needs to be deprecated in 3.6.2; {@inheritDoc} didn't seem to apply
> the deprecation)
> public T nullSafeGet(ResultSet rs, String name)
> public Object get(ResultSet rs, String name)
> public void nullSafeSet(PreparedStatement st, T value, int index)
> public void set(PreparedStatement st, T value, int index)
> NO_OPTIONS (no longer needed in master)
OK (to me the deprecation applies to the API overall)
> 3) In UserType in master:
> - remove
> Q: people complain if a method is deprecated w/o providing the
> preferred method;
> providing the preferred method in 3.6.2 would break UserType;
> should this just be documented as a breaking change in the
> migration guide?
I've already defended this many many times. People are always going to be
unhappy about something. I firmly believe this is the right approach.
> public Object nullSafeGet(ResultSet rs, String[] names, Object
> owner)
> public void nullSafeSet(PreparedStatement st, Object value, int
> index)
> - add to master:
> public Object nullSafeGet(ResultSet rs, String[] names,
> SessionImplementor session, Object owner)
> public void nullSafeSet(PreparedStatement st, Object value, int
> index, SessionImplementor session)
>
> 4) update references to removed methods in master
Well yeah ;)
>
> I don't want to break other software that is trying to integrate with
> H4. I don't want to get slapped like when I removed ServiceRegistry from
> Configuration.
Not sure about the point here. Making breaking changes is going to break
people's uses. IMO we got into trouble with ServiceRegistry because its not
really ready yet and we should have hidden it for a bit longer. For
integrators I usually recommend they implement through Type rather than
UserType.
>
> So, should I wait on these changes, or would it suffice to give a heads
> up about these changes on the hibernate-dev mailing list?
>
> Is there a migration guide for H4?
Yep, http://community.jboss.org/wiki/HibernateCoreMigrationGuide40
> Please let me know.
>
> Thanks,
> Gail
>
> Steve Ebersole wrote:
> > For sure now is the time to make whatever change we are going to make.
> >
> > I for one say +1
> >
> > Furthermore I think we should evaluate the overloaded
> > nullSafeGet/nullSafeSet methods on Type
> >
> > On Feb 17, 2011 9:39 PM, "Gail Badner" <gbadner(a)redhat.com
> >
> > <mailto:gbadner@redhat.com>> wrote:
> > > I noticed that UserType.nullSafeSet() and nullSafeGet() don't have a
> > > SessionImplementor argument, but those methods in CompositeUserType do
> > > have it.
> > >
> > > This might not make a difference in 3.6.x, but in H4, not having the
> > > SessionImplementor argument makes it impossible to do dynamic type
> > > overrides specified by the dialect.
> > >
> > > As an example, suppose a UserType delegates nullSafeGet()/nullSafeSet()
> > > to StandardBasicTypes.BLOB.nullSafeGet()/nullSafeSet(). True, the
> > > UserType could delegate to the proper type (streaming or lob-binding).
> > > To be able to use the same UserType for, say, both Oracle and
> > > PostgreSQL, it would have to be possible to do the override based on
> > > dialect.
> > >
> > > I think the right thing to do is add the SessionImplementor argument
> >
> > for H4.
> >
> > > Comments?
> > >
> > > Gail
> > >
> > >
> > >
> > > _______________________________________________
> > > hibernate-dev mailing list
> > > hibernate-dev(a)lists.jboss.org <mailto:hibernate-dev@lists.jboss.org>
> > > https://lists.jboss.org/mailman/listinfo/hibernate-dev
---
Steve Ebersole <steve(a)hibernate.org>
http://hibernate.org
13 years, 9 months
Cascading Lock - or re-associating object graph to an open session
by Sanne Grinovero
Hi all,
I'm needing some advice about HSEARCH-689 - MassIndexer throwing
LazyInitializationException on associated collections.
MassIndexer design reminder:
Search loads the root entity it needs to index via a Session A,
attempting to initialize as less collections as possible,
then it sends these objects to a queue, consumed by a second thread
having Session B opened; this takes the objects from the queue and
attaches them to their own session to continue processing.
- Session A detaches objects using
session.clear()
- Session B attaches objects using
session.buildLockRequest( LockOptions.NONE ).lock( take );
Now in the particular case of this issue, the object loaded by A is
having a property containing an AbstractPersistentCollection, which is
send to second thread un-initialized.
When Session B iterates over this collection, while the object is
attached, it seems the collection is not, as:
org.hibernate.collection.AbstractPersistentCollection.isConnectedToSession()
returns false because session==null;
I just verified that if this collection is annotated with
cascade={CascadeType.ALL}, then the "lock none" operation seems to be
propagated to the collection, and the indexer works.
(Same with @Cascade(value = { org.hibernate.annotations.CascadeType.LOCK }) )
So a quick workaround for this is to use the CascadeType.ALL, but what
is a batter solution for the MassIndexer ?
options:
A) DocumentBuilderIndexedEntity.java:466 should make sure the
AbstractPersistentCollection is attached, or attach it if needed.
but we would like this code area to be Hibernate independent.
B) Have core provide some method like "lock entity and all linked
collections recursively", something which performs the same as the
cascading annotations. Note that I don't need support for locking,
just LockOptions.NONE as a trick to attach the full graph.
Better ideas?
Sanne
13 years, 9 months
Hibernate Search 3.4 release train
by Emmanuel Bernard
Hi,
We have targeted v 3.4 for end of march.
What do you think of doing an Alpha1 within the next two weeks?
For reference, the list of todo we had for 3.4 is:
- Use 2LC for object load (emmanuel, done)
- Tx and JMS (sanne)
- Faceting (hardy)
- Benchmark (sanne, not sure what the detail was)
- FieldCache usage (sanne)
- Abstract from Core (emmanuel)
We also already have a few bug fixes and a few non planned new features:
- multi-threads used in text analysis for MassIndexer
- Infinispan 4.2.1 (CR1)
- index on indexed entity change
- MassIndexer monitoring
Which feature do you think can go into Alpha1?
Emmanuel
13 years, 9 months
[Validator] Method level validation and cross parameter validator
by Emmanuel Bernard
Reading the Google design by contract work, I realized that we do not cover cross-parameter validation in method-level validation.
//We want to make sure departure is after arrival.
void book(Date arrival, Date departure);
Any idea on ow best to address that?
13 years, 9 months