[hibernate-dev] Hibernate Search Metadata API: Numeric and other special Field types in Hibernate Search
Emmanuel Bernard
emmanuel at hibernate.org
Tue Jul 16 04:41:19 EDT 2013
Like gunnar, I was thinking that a type property and an unwrapping
method would do the trick. Though I'd favor delegation over
subclassing.
On Tue 2013-07-16 9:27, Gunnar Morling wrote:
> Hi,
>
> > I won't mention my favorite Vattern. I've considered adding subtypes
> but not liking it as their usage would not be clear from the API.
>
> How would you use your vavorite Vattern without subtypes? And which other
> option would you prefer then?
>
> I think the field-type specific information can either be on
>
> a) FieldSettingsDescriptor itself (as is today)
> b) specific subtypes of FSD
> c) specific delegates of FSD, safely accessible via a type parameter of FSD
>
> a) would IMO be the simplest but could lead to a proliferation of
> attributes on FSD; So as you say it depends on the number of specific
> attributes whether its feasible or not. But even if sticking to this
> approach, we might consider to replace boolean isNumeric() with FieldType
> getFieldType(). This would avoid adding a new isXy() method for each
> specific type and be used like so:
>
> if ( desc.fieldType = NUMERIC) {
> doSomething( desc.precisionStep() );
> else if ( desc.fieldType = FOO ) {
> doSomething( desc.fooAttrib() );
> }
>
> For b), you need a way to narrow down to the subtype, either via Visitor or
> some kind of cast. I still find this pattern as used in BV reads quite
> nicely:
>
> Object result = null;
> if ( desc.fieldType = NUMERIC) {
> result = doSomething( desc.as( NumericDescriptor.class).precisionStep()
> );
> else if ( desc.fieldType = FOO ) {
> result doSomething( desc.as( FooDescriptor.class).fooAttrib() );
> }
>
> In particular, as() would only accept subtypes of Descriptor and be thus a
> bit safer than a plain downcast.
>
> Btw., the annotation processing API (as e.g. used by the Meta model
> generator or the AP in Hibernate Validator), offers both ways for that
> purpose, i.e. a visitor approach and, getKind() + downcast. Having worked
> with both, I find the usually simpler to use.
>
> For a comparison, the last example would look like this with a visitor
> design similar to the annotation processing API (the type parameters are
> for parameter and return type passed to/retrieved from the visitor):
>
> Object result = desc.accept(
> new FieldDescriptorVisitor<Void, Object>() {
>
> @Override
> Object visitAsNumber(NumberDescriptor descriptor, Void p) {
> return doSomething( descriptor.precisionStep() );
> }
>
> @Override
> Object visitAsFoo(FooDescriptor descriptor, Void p) {
> return doSomething( descriptor.fooAttrib() );
> }
> }
> );
>
> Personally, I find this reads and writes not as nice as the other approach.
>
> Regarding c), one could think of something like this:
>
> class FieldSettingsDescriptor<T extends DescriptorSpecifics> {
> public T getSpecifics();
> ...
> }
>
> and
>
> FieldSettingsDescriptor<NumberSpecifics> numberDescriptor = ...;
> doSomething( numberDescriptor.getSpecifics().precisionStep() );
>
> But the question is how one would obtain a properly typed descriptor. E.g.
> from a collection with mixed fields, one would only get
> FieldSettingsDescriptor<?>, making this quite pointless.
>
> I think, I'd like the getType()/as() approach best. Or do you have yet
> another approach in mind?
>
> --Gunnar
>
>
>
> 2013/7/15 Sanne Grinovero <sanne at hibernate.org>
>
> > The new FieldSettingsDescriptor [1] has a couple of methods meant for
> > Numeric fields:
> >
> > /**
> > * @return the numeric precision step in case this field is indexed as
> > a numeric value. If the field is not numeric
> > * {@code null} is returned.
> > */
> > Integer precisionStep();
> >
> > /**
> > * @return {@code true} if this field is indexed as numeric field,
> > {@code false} otherwise
> > *
> > * @see #precisionStep()
> > */
> > boolean isNumeric();
> >
> > Today we have specific support for the
> > org.apache.lucene.document.NumericField type from Lucene, so these are
> > reasonable (and needed to build queries) but this specific kind is
> > being replaced by a more general purpose encoding so that you don't
> > have "just" NumericField but can have a wide range of special fields.
> >
> > So today for simplicity it would make sense to expose these methods
> > directly on the FieldSettingsDescriptor as it makes sense for our
> > users, but then also the #isNumeric() is needed as not all fields are
> > numeric: we're having these extra methods to accommodate for the needs
> > of some special cases.
> >
> > Considering that we might get more "special cases" with Lucene4, and
> > that probably they will have different options, would we be able to
> > both decouple from these specific options and also expose the needed
> > precisionStep ?
> >
> > I won't mention my favorite Vattern. I've considered adding subtypes
> > but not liking it as their usage would not be clear from the API.
> >
> > Cheers,
> > Sanne
> >
> > 1 - as merged two minutes ago
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> >
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
More information about the hibernate-dev
mailing list