elasticsearch php不返回没有空格的搜索结果

vcirk6k6  于 2021-06-14  发布在  ElasticSearch
关注(0)|答案(2)|浏览(639)

我在elasticsearch索引中添加了15k条记录 products_idx1 和类型 product .
记录产品名称,如 apple iphone 6 所以当我寻找 iphone6 它返回空数据。
这是我在php elasticsearch中的代码

<?php

    use Elasticsearch\ClientBuilder;

    require 'vendor/autoload.php';

   $client = ClientBuilder::create()->build();
 $values =['name','name.prefix','name.suffix','sku'];
$params =
[
'client'=>['verify'=>1,'connect_timeout'=>5],
'from'=> 0,
'size'=>25,
 'body'  =>[
'query' => [
 'bool'=>
            [
            'should'=> [[
                'multi_match'=> ['query'=>'iphone6','type'=>'cross_fields','fields'=>$values,'operator'=>'OR']
                ],
                ['match'=>['all'=>['query'=>'iphone6','operator'=>'OR','fuzziness'=>'AUTO'] ]]
                ]
            ]

],
'sort'=>['_score'=>['order'=>'desc']],
],

'index'=>'products_idx1'
];

 $response = $client->search($params);
echo "<pre>";print_r($response);
vjrehmav

vjrehmav1#

使用shingle和pattern\u replace token过滤器可以得到问题和注解中提到的所有3个搜索词的结果 iphone , iphone6 以及 appleiphone 下面是一个完整的例子。
正如注解中所解释的,为了得到搜索结果,从搜索项生成的搜索时间标记应该与从索引文档生成的索引时间标记匹配,这就是我通过创建自定义分析器所实现的。
索引Map

{
  "settings": {
    "analysis": {
      "analyzer": {
        "text_analyzer": {
          "tokenizer": "standard",
          "filter": [
            "shingle",
            "lowercase",
            "space_filter"
          ]
        }
      },
      "filter": {
        "space_filter": {
          "type": "pattern_replace",
          "pattern": " ",
          "replacement": "",
          "preserve_original": true
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "text_analyzer"
      }
    }
  }
}

索引您的样本文档

{
  "title" : "apple iphone 6" 
}

搜索查询 appleiphone 有结果的

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "appleiphone"
          }
        }
      ]
    }
  }
}

结果

"hits": [
      {
        "_index": "ana",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.3439677,
        "_source": {
          "title": "apple iphone 6",
          "title_normal": "apple iphone 6"
        }
      }
    ]

搜索查询 iphone6 有结果的

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "iphone6"
          }
        }
      ]
    }
  }
}

结果

"hits": [
      {
        "_index": "ana",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.3439677,
        "_source": {
          "title": "apple iphone 6",
          "title_normal": "apple iphone 6"
        }
      }
    ]

最后但不是最不重要的搜索查询 iphone ```
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "iphone"
}
}
]
}
}
}

结果

"hits": [
{
"_index": "ana",
"_type": "_doc",
"_id": "1",
"_score": 0.3439677,
"_source": {
"title": "apple iphone 6",
"title_normal": "apple iphone 6"
}
}
]

e7arh2l6

e7arh2l62#

因为我的答案已经很大了,为了可读性的原因,为了不熟悉elasticsearch中的分析器以及它的工作原理的人,我在另一个答案中添加了关于analyze api的信息。
在我之前的回答中,@niraj提到了其他文件正在工作,但他对这个问题有异议 iphone6 所以为了调试问题分析api是非常有用的。
首先检查文档的索引时间标记,您认为该标记应该与本例中的搜索查询相匹配, apple iphone 6 放入http://{{hostname}}:{{port}}/{{index}}/\u分析

{
"text" : "apple iphone 6",
"analyzer" : "text_analyzer"
}

和生成的代币

{
"tokens": [
{
"token": "apple",
"start_offset": 0,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "appleiphone",
"start_offset": 0,
"end_offset": 12,
"type": "shingle",
"position": 0,
"positionLength": 2
},
{
"token": "iphone",
"start_offset": 6,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "iphone6", //note this carefully
"start_offset": 6,
"end_offset": 14,
"type": "shingle",
"position": 1,
"positionLength": 2
},
{
"token": "6",
"start_offset": 13,
"end_offset": 14,
"type": "<NUM>",
"position": 2
}
]
}

现在你可以看到我们使用的分析器 iphone6 同样作为一个标记,现在检查搜索时间标记

{
  "text" : "iphone6",
  "analyzer" : "text_analyzer"
}

和代币

{
    "tokens": [
        {
            "token": "iphone6",
            "start_offset": 0,
            "end_offset": 7,
            "type": "<ALPHANUM>",
            "position": 0
        }
    ]
}

现在你可以注意到搜索标记也创建了 iphone6 作为索引时间标记中的一个标记,所以它将匹配我在第一个答案中给出的完整示例中已经显示的搜索查询

相关问题