gpt4 book ai didi

php - Laravel Elasticsearch 不给出包含或喜欢的匹配

转载 作者:行者123 更新时间:2023-12-03 01:33:39 25 4
gpt4 key购买 nike

我想为所有的Laravel搜索查询实现elasticsearch。我使用brew安装了最新的Laravel和最新的elasticsearch。
curl http://localhost:9200/给出了

{
"name" : "_SFvSGk",
"cluster_name" : "elasticsearch_an398690",
"cluster_uuid" : "xBi3aTDaTkmA6dtzhpOrwg",
"version" : {
"number" : "6.5.4",
"build_flavor" : "oss",
"build_type" : "tar",
"build_hash" : "d2ef93d",
"build_date" : "2018-12-17T21:17:40.758843Z",
"build_snapshot" : false,
"lucene_version" : "7.5.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}

在这里,我正在使用 driver babenkoivan/scout-elasticsearch-driver

模型
namespace App;

use ScoutElastic\Searchable;
use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
use Searchable;

/**
* @var string
*/
protected $indexConfigurator = CustomerIndexConfigurator::class;

/**
* @var array
*/
protected $searchRules = [
CustomerSearchRule::class
];

/**
* @var array
*/
protected $mapping = [
'properties' => [
'text' => [
'type' => 'text',
'fields' => [
'ref_num' => [
'type' => 'keyword',
]
]
],
]
];
}

SearchRule
namespace App;

use ScoutElastic\SearchRule;

class CustomerSearchRule extends SearchRule
{
/**
* @inheritdoc
*/
public function buildHighlightPayload()
{
return [
'fields' => [
'ref_num' => [
'type' => 'plain'
]
]
];
}

/**
* @inheritdoc
*/
public function buildQueryPayload()
{
$query = $this->builder->query;

return [
[
'match' => [
'ref_num' => [
'query' => $query,
'boost' => 2
]
]
]
];
}
}

配置程序
namespace App;

use ScoutElastic\IndexConfigurator;
use ScoutElastic\Migratable;

class CustomerIndexConfigurator extends IndexConfigurator
{
use Migratable;

/**
* @var array
*/
protected $settings = [
//
];
}

我有一条记录,其中 ref_numI50263。因此,当我像 I50一样搜索 like query时,应该获得此记录。我尝试了以下所有搜索,但仅使用完整的单词 I50263获得了结果。
return Customer::search('I50')->get();
// no record
return Customer::search('I50263')->get();
// got record
return Customer::searchRaw([
'query' => [
'bool' => [
'must' => [
'match' => [
'ref_num' => 'I502'
]
]
]
]
]);
// no record
return Customer::searchRaw([
'query' => [
'bool' => [
'must' => [
"match_phrase" => [
"ref_num" => [
"query" => "I50",
"boost" => 1
]
]
]
]
]
]);
// no record

尝试将字段类型也设置为 text

最佳答案

如我所见,您的ref_num字段是keyword类型。执行full-text queries(如matchmatch_phrase)不会给您任何结果。对于keyword -s,您应该使用term level queries。也许prefix query在这里对您有所帮助。



制图

PUT /so54176561
{
"mappings": {
"_doc": {
"properties": {
"ref_num": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
}

添加样本文件
POST /so54176561/_doc/1
{
"ref_num": "I50263"
}

match类型字段上搜索全文 text
按全部值(value)
POST /so54176561/_search
{
"query": {
"match": {
"ref_num": "I50263"
}
}
}

结果:找到 文档

通过值的前缀
POST /so54176561/_search
{
"query": {
"match": {
"ref_num": "I50"
}
}
}

结果:找不到 文档

prefix类型字段上搜索术语级别 keyword
POST /so54176561/_search
{
"query": {
"prefix": {
"ref_num.raw": "I50"
}
}
}

结果:找到 文档

如您所见,在示例中,我使用了这种子字段( rawref_num的子字段,但类型不同)。在Elasticsearch中,它称为 fields,您可以在 documentation中阅读更多信息。

您可以使用 bool query将该查询与任何其他字段上的任何其他查询一起简单地使用。

如果要在 text type字段上获得相同的结果,则必须正确准备索引。例如,您可以将自定义分析器与 NGram tokenizer结合使用,它将单词分解为n-gram标记。

默认情况下,任何分析器都不会拆分单词,因此在您的情况下,索引中只有一个标记:
POST /_analyze
{
"analyzer": "standard",
"text": "I50263"
}

结果:
{
"tokens": [
{
"token": "i50263",
"start_offset": 0,
"end_offset": 6,
"type": "<ALPHANUM>",
"position": 0
}
]
}

对于全文搜索,Elasticsearch基于其在索引中的标记。如果 token 与搜索项中的 token 不匹配,则没有匹配项。

关于php - Laravel Elasticsearch 不给出包含或喜欢的匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54176561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com