elasticsearch匹配phrase_prefix等

时间:2015-11-09 10:52:31

标签: php elasticsearch elastica

嗨我有弹性搜索的问题, 我有一些像

的结果
  
      
  • 模件'离子
  •   
  • 测试锂文件
  •   

当我查询是否输入' mod'我没有找到结果,我添加了类型:" phrase_prefix"到我的查询,现在我找到了结果

  

模件'离子

但现在当我输入锂时,a找不到结果

  

测试锂文件

我的要求

    $query ['match'] ['_all'] ["query"] = strtolower ( $keyword );
    $query ['match'] ['_all'] ["type"] = "phrase_prefix";
    $query ['match'] ['_all'] ["analyzer"] = "synonym";

我也使用同义词分析器,其中包含"锂=>可充电锂" 我的问题是如果a不使用分析仪或我删除

  

$ query ['匹配'] [' _all'] ["输入"] =" phrase_prefix&#34 ;;

我找到了结果,但是' mod'又回来了所以我想在两种情况下得到结果你能帮帮我吗?

我使用此查询设置分析器

 {"analysis" : {
    "analyzer" : {
        "synonym" : {
            "tokenizer" : "whitespace",
            "filter" : ["synonym"]
        }
    },
"filter" : {
            "synonym" : {
                "type" : "synonym",
                "synonyms_path" : "synonym.txt",
                "ignore_case" : true
            }
        }
    }
}

2 个答案:

答案 0 :(得分:3)

首先,我认为你的映射没有任何问题,它们在后端工作得很好。您的问题是您要查询_all字段,该字段需要单独配置。如果您没有指定它,它将具有默认参数,可以看到here。为了改变这种情况,我使用了这些设置和映射:

PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "whitespace",
          "char_filter": ["my_mapping"],
          "filter": [
            "lowercase",
            "my_synonym"
          ]
        }
      },
      "filter": {
        "my_synonym": {
          "type": "synonym",
          "ignore_case": true,
          "synonyms": [
            "rechargeable lithium => lithium"
          ]
        }
      },
      "char_filter": {
        "my_mapping": {
          "type": "mapping",
          "mappings": [
            "'=>"
          ]
        }
      }
    }
  },
  "mappings": {
    "test": {
      "_all": {
        "enabled": true,
        "analyzer": "my_analyzer"
      }
    }
  }
}

这些设置会在空白处打破您的令牌,从令牌中删除引号并将它们小写,以便:

  • modul'ion将被编入索引modulion,每当用户输入任何这些短语时,他都会找到它。
  • rechargeable lithiumlithium替换为同义词。
  • 由于lowercase过滤,因此您的搜索不区分大小写。

使用这些映射我已将您的数据添加到索引中:

PUT /test/test/1
{
  "text": "modul'ion"
}

PUT /test/test/2
{
  "text": "test lithium file"
}

现在运行此查询:

POST /test/test/_search
{
  "query": {
    "match": {
      "_all": {
        "query": "rechargeable lithium",
        "type": "phrase_prefix"
      }
    }
  }
}

返回此文档:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.15342641,
    "hits": [
      {
        "_index": "test",
        "_type": "test",
        "_id": "2",
        "_score": 0.15342641,
        "_source": {
          "text": "test lithium file"
        }
      }
    ]
  }
}

以下两个查询:

POST /test/test/_search
{
  "query": {
    "match": {
      "_all": {
        "query": "mod",
        "type": "phrase_prefix"
      }
    }
  }
}

POST /test/test/_search
{
  "query": {
    "match": {
      "_all": {
        "query": "modulion",
        "type": "phrase_prefix"
      }
    }
  }
}

返回:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.30685282,
    "hits": [
      {
        "_index": "test",
        "_type": "test",
        "_id": "1",
        "_score": 0.30685282,
        "_source": {
          "text": "modul'ion"
        }
      }
    ]
  }
}

这只是RAW JSON查询,但我想你可以在PHP中处理这些问题。

答案 1 :(得分:0)

问题不是查询类型,而是同义词。同义词过滤器通常用于将术语替换为另一个术语,而不是术语替换整个术语,因为该术语不会在之后被标记化。

您必须知道分析使用了两次:一次是索引,另一次是搜索。让我们假设您的文档使用标准分析器(默认分析器)进行分析:

  • 输入" modul'离子" →1索引术语:"模块"
  • 输入"测试锂文件" →3个索引条款:"测试","锂","文件"

如果您使用phrase_prefix搜索标准分析(无同义词):

  • 输入" mod" →1搜索词前缀" mod"发现在#1
  • 输入"锂" →1搜索词前缀"锂"发现在#2
  • 输入"测试锂电池" →2搜索术语前缀"测试","锂"发现在#2

如果您正在使用自定义分析器(同义词)进行搜索

  • 输入" mod" →1搜索词前缀" mod"发现在#1
  • 输入"锂" →1搜索术语前缀"可充电锂电池"找不到
  • 输入"测试锂电池" →2搜索术语前缀"测试","可充电锂电池"找不到

如果您使用小写进行索引(索引时的分析链包含小写过滤器),您还应该谨慎使用大小写,不要尝试大写搜索(搜索时的分析链产生" Lithium"而不是"锂")。

如果您是Elasticsearch的新手,我建议您:

  1. 从索引和搜索的相同分析设置开始。您已经知道如何配置分析器,只需使用Put Mapping API配置索引
  2. 使用Analyze API
  3. 测试分析链

    例如:

    PUT the_index/_mapping/the_type 
    {
      "properties": {
        "the_field": {
          "type": "string",
          "analyze": "the_analyzer"
        }
      }
    }
    
    GET the_index/_analyze?analyzer=synonym&text=modul'ion
    GET the_index/_analyze?analyzer=synonym&text=test lithium