在Lucene Java中索引和搜索非字母字符

时间:2013-04-15 12:13:30

标签: java lucene

Lucene(Java)的已使用版本是4.2.1,用于索引和搜索的已用分析器是org.apache.lucene.analysis.core.WhitespaceAnalyzer。 下面的代码在Scala中,但我认为对于具有C语言经验的人来说,它很容易阅读。

问题在于: 我还需要使用非alpha字符索引和搜索文本。 例如,我有名称的实体:“名称1”,“名称2”,“名称3”,...我希望能够搜索“名称2”或“2”或甚至“我2” ”

到目前为止我已经

字段:

val textField = new TextField("text", theFullText, Field.Store.NO)

和查询:

val parser = new QueryParser(version, "text", analyzer)

// case-sensitive search
parser.setLowercaseExpandedTerms(false)   // removed when MyAnalyzer is used

// To be able to search for text in the middle. Makes searches slower when the index is big!
parser.setAllowLeadingWildcard(true)

val textWithWildcard = s"*${QueryParserBase.escape(text)}*"

val textQuery = parser.parse(textWithWildcard)
booleanQuery.add(textQuery, BooleanClause.Occur.MUST)
val topDocs: TopDocs = searcher.search(booleanQuery, 9999)
val hits: Array[ScoreDoc] = topDocs.scoreDocs
hits.map(_.doc) // return an Array of ScoreDocs' ids

一个简单的单元测试:

"be able to search numbers" {
  for (idx <- 1 to 10) {
    val entity = new Entity
    entity.id = idx
    entity.name = s"name ${idx}"

    indexingService.index(entity)
  }


  val ids: Seq[Int] = indexingService.search[Entity]("name 3")
  ids.length must_==(1)
}

即。创建10个实体,然后搜索第三个实体。问题是结果是0。

想法在我的配置中要更改哪些内容才能使其正常工作?

更新: 我已经创建了自己的分析器,以支持不区分大小写的搜索:

class MyAnalyzer(ver: Version) extends Analyzer {

   protected def createComponents(fieldName: String, reader: Reader): Analyzer.TokenStreamComponents = {
      val tokenizer = new WhitespaceTokenizer(ver, reader)
      val lowerCaseFilter = new LowerCaseFilter(ver, tokenizer)
      val tsc = new Analyzer.TokenStreamComponents(tokenizer, lowerCaseFilter)
      tsc
   }
 }

现在结果 10 ! 再次这不是所希望的,因为测试搜索“名称3”但返回所有实体,即似乎数字在索引和搜索时间都被剪切。

2 个答案:

答案 0 :(得分:0)

要在字段中一起搜索一组单词,请用双引号括起单词。

我相信你可以跳过通配符(名称和3之间没有任何内容)。

val textWithWildcard = s"\"${QueryParserBase.escape(text)}\""

编辑:给你10个结果是正确的行为,因为返回的文档有不同的分数。 当您按实体搜索时,您需要能够区分完全匹配查询和部分匹配查询。

答案 1 :(得分:0)

解决方案是添加:

parser.setDefaultOperator(Operator.AND)

我之前尝试过,但由于某些原因它没有用。我想其他一些设置也有问题。