2

Integrated the QueryParser of Lucene in to my application's search. I have a stringField for which i have to perform some comparison operators also.

eg: age>3 age<4

But i cannot make the field Int.Because sometimes it may have the string values like "NIL","Undefined" etc.

So is there anyway to apply multiple types to the same field.Or is it possible to apply comparison operators with the stringField itself? Please help.

Nidhin Joseph
  • 1,461
  • 3
  • 15
  • 32

2 Answers2

2

Use Range query:

  • age:[3 TO 5] equivalent to age between 3 and 5 (inclusive)
  • age:[3 TO *] equivalent to age > 3

It will work for String type also.
Reference: http://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Range%20Searches

GS Majumder
  • 999
  • 6
  • 8
  • 1
    age:{3 TO 5} with a string field should match, say, "333" and "499999" because of alphanumeric ordering. Probably not what you want. – ArtemGr Aug 21 '13 at 11:45
0

[If you really need the original value of the field then]
Keep the original in a separate Lucene field, e.g. "originalAge".

P.S. It seems you can control the query parser to some extent by overriding getFieldQuery. That way it should be possible to delegate text queries to the text field, while keeping numeric queries to the integer field. Scala sample:

val qp = new org.apache.lucene.queryparser.classic.QueryParser (Version.LUCENE_43, "age", ANALYZER_RUS) {
  override def getFieldQuery (field: String, queryText: String, quoted: Boolean): org.apache.lucene.search.Query = {
    println (s"getFieldQuery ($field, $queryText, $quoted)")
    if (field == "age") {
      if (queryText.matches ("^age(\\>|\\<)\\d+$")) super.getFieldQuery (field, queryText, quoted)
      else super.getFieldQuery ("originalAge", queryText, quoted)
    } else super.getFieldQuery (field, queryText, quoted)
  }
}
println (qp.parse ("undefined"))  // originalAge:undefined
println (qp.parse ("age>3"))  // age:age age:3

You might also check the flexible query parser.

ArtemGr
  • 11,684
  • 3
  • 52
  • 85
  • I am ready to keep them in two separate Fields(one intField where the integer values are kept and other StringField where string values like nill,undefined and all). But finally the user will only search for "age". Can i map the searches to "orginalAge" also. ie. if the user searches like age:undefined => (ie.String search)the search have to be against the field originalAge age<23 => (ie.Integer search) the search have to be made against "age" – Nidhin Joseph Aug 21 '13 at 09:08
  • I have updated the answer to address conditional mapping of "age" to "originalAge". – ArtemGr Aug 21 '13 at 11:43