在Java Lucene上模拟弹性搜索索引和查询

时间:2019-01-24 12:29:37

标签: elasticsearch lucene

您好,我正在使用弹性搜索,但是我想迁移到Java Lucene。

我需要以相同的方式重新创建索引并以相同的方式重新创建查询。我虽然做到了,但是从查询中得到的分数却不太一样。结果非常相似,但是结果本身的分数不同。也许我缺少了一些东西。我找不到足够的信息,默认的弹性设置在Lucene中是等效的。

我已经检查了我的Lucene版本是否与我使用的弹性搜索相同

我将向您展示我的弹性构型以及如何在Lucene上复制它。

这是我用于创建索引的弹性搜索连接器:

"analysis": {
   "analyzer": {
            "default": {           
               "tokenizer": "standard",           
                "filter":  [ "lowercase", "asciifolding" ]
             }
    }     
}

这些是我的查询

Query1)

 "query": {
      "dis_max": {
           "queries": [
                { "match": { "field1": "${term}" }}
           ],
      "tie_breaker": 1
     }
 }

查询2)

 "query": {
      "dis_max": {
           "queries": [
                { "match": { "field1": "${term}" }},
                { "match": { "field2": "${term}" }},
                { "match": { "field2":  "${term}" }}
           ],
           "tie_breaker": 1
      }
 }

以下是Scala代码:

这些是创建Lucene索引时我的field1, field2 and field3选项:

 val CustomStringFieldType: FieldType = {
     val fieldType = new FieldType()
     fieldType.setStoreTermVectors(true)
     fieldType.setStoreTermVectorPositions(true)
     fieldType.setOmitNorms(false)
     fieldType.setTokenized(true)
     fieldType.setStored(false)
     fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS)
     fieldType.freeze()
     fieldType
   }

我使用doc.add(new Field("field1", field1Value, CustomStringFieldType))将字段添加到文档中。

这些是我的查询。我正在使用Standard Analyzer创建令牌,并且正在使用BM25相似度算法:

  def query1(tokens: Seq[String]): Query = {

     var booleanQueryBuilder = new BooleanQuery.Builder()

     for (token <- tokens) {
       booleanQueryBuilder = booleanQueryBuilder.add(
         new TermQuery(new Term("field1", token)),
         BooleanClause.Occur.SHOULD)
     }
     booleanQueryBuilder.build()
   }

 def query2(tokens: Seq[String]): Query = {

     val queries = new java.util.ArrayList[Query]()

     for (field <- ("field1", "field2", "field3") {

       var booleanQueryBuilder = new BooleanQuery.Builder()

       for (token <- tokens) {
         booleanQueryBuilder = booleanQueryBuilder.add(
           new TermQuery(new Term(field, token)),
           BooleanClause.Occur.SHOULD)
       }

       val booleanQuery: BooleanQuery = booleanQueryBuilder.build()
       queries.add(booleanQuery)
     }
     new DisjunctionMaxQuery(queries, broadQueryTieBreaker)
   }

1 个答案:

答案 0 :(得分:1)

明显的区别是您的映射设置。

虽然您选择在Lucene中具有以下条件

fieldType.setStoreTermVectors(true)
fieldType.setStoreTermVectorPositions(true)
fieldType.setOmitNorms(false)
fieldType.setTokenized(true)
fieldType.setStored(false)
fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS)

默认情况下,在Elasticsearch中:

term_vector-默认情况下处于禁用状态,因此您需要

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "text": {
          "type":        "text",
          "term_vector": "with_positions"
        }
      }
    }
  }
}

要像在Lucene中一样存储职位。

因此,由于您要迁移到Lucene,因此需要禁用术语向量,就像它们在您的Elasticsearch中一样