[hibernate-dev] Hibernate Search Metadata API: Numeric and other special Field types in Hibernate Search

Gunnar Morling gunnar at hibernate.org
Tue Jul 16 03:27:33 EDT 2013


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
>


More information about the hibernate-dev mailing list