How can you add numeric fields in Nhibernate.Search?

423 views Asked by At

I recently mitakenly assumed that Nhibernate.Search would index an integer property on my class as a numeric field.

[Indexed]
public class Location : Entity
{
    [IndexedEmbedded(Depth = 1, Prefix = "Country_")]
    public virtual Country Country { get; set; }
    [Field(Index.Tokenized)]
    public virtual string Name { get; set; }
    [Field(Index.Tokenized)]
    public virtual string AlternativeNames { get; set; }
    [Field(Index.Tokenized)]
    public virtual string OriginalNames { get; set; }
    [Field(Index.UnTokenized)]
    public virtual string LocationType { get; set; }
    [Field()]
    public virtual int? Population   { get; set; }
}

But when I set the sort for the query like so:

 var words = query.Split(' ');

        var luceneQuery = string.Join(" AND ", words.Select(x => "Name:{0}*".F(x)));
        luceneQuery += " AND LocationType:locality";
        var results = search.CreateFullTextQuery<Location>(luceneQuery)
           .SetSort(new Sort(new SortField("Population", CultureInfo.CurrentCulture, true)))
            .SetMaxResults(100)
            .List<Location>();

It returns results ordered by the numbers in the same style as a word sort like this:

City       Country          Region          Population
New London     United States    North America   998
Nueva Londres  Paraguay         South America   971
New London     United States    North America   967
Londonderry    United Kingdom   British Islands 92133
London     Kiribati         Micronesia  921
London     United States    North America   8122
London     United Kingdom   British Islands 7869322
New London     United States    North America   7316

So my question is, as Nhibernate.Search is treating this as a text field, how can I change it to a numeric field and is it possible to convert or do I have to reindex every single record. 340K of them.

I am starting to feel the convenience of Nhibernate.Search is lost if it cannot do this. Maybe I will have to start over and use normal Lucene.Net?

Thanks for any help

2

There are 2 answers

2
JSuar On

Update

Possible helpful links:


I think both your questions, on numeric and range searches, are addressed here: http://find.searchhub.org/link?url=http://wiki.apache.org/lucene-java/SearchNumericalFields

Because Apache Lucene is a full-text search engine and not a conventional database, it cannot handle numerical ranges (e.g., field value is inside user defined bounds, even dates are numerical values). We have developed an extension to Apache Lucene that stores the numerical values in a special string-encoded format with variable precision (called trie, all numerical values like doubles, longs, Dates, floats, and ints are converted to lexicographic sortable string representations and indexed with different precisions).

...

Numeric fields can be sorted on (a special parser is included into FieldCache) and used in function queries (through FieldCache)

I also found a LongClass.java implementation via Range searches for numbers:

I implemented a "LongField" that encodes any +ve or -ve long into a string that sorts correctly. I posted that class here: http://www.mail-archive.com/[email protected]/msg04790.html

Doing a String range search should be fairly straight forward from there. Let me know if you have any problems.

0
Silmarillium On

I know this is for hibernate.search and not for NHibernate.search, but isn't there a [NumericField] that you can specify on your column ? (as all the rest resembles ;-)

http://docs.jboss.org/hibernate/search/3.3/reference/en-US/html_single/#basic-mapping (4.1.1.3. @NumericField)