当前位置: 首页 > 知识库问答 >
问题:

Laravel Elasticsearch JSON映射问题

谭俊
2023-03-14

我目前正在使用Laravel v7。2.安装babenkoivan/scout elasticsearch驱动程序(4.2)并使用AWS elasticsearch 7.1调幅。在我的应用程序中映射了几个表,这些表工作正常,但嵌套映射存在问题,以前该映射工作正常,现在已损坏。

我将数据保存到一个表中,并将该表数据复制到AWS Elasticsearch中。我使用MySQL 5.6,所以我使用TEXT列来存储JSON数据。表中的数据如下:

'id' => 1,
'results' => [{"finish":1,"other_id":1,"other_data":1}]

我有我的模型设置与以下映射:

protected $mapping = [
        'properties' => [
            'results' => [
                'type' => 'nested',
                'properties' => [
                    'finish' => [
                        'type' => 'integer'
                    ],
                    'other_id' => [
                        'type' => 'integer'
                    ],
                    'other_data' => [
                        'type' => 'integer'
                    ]
                ]
            ],
        ]
    ];

如果有用的话,ToSearchLearray:

public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'results' => $this->results
        ];

        return $array;
    }

我创建这个索引没有问题,直到大约几个月前它才开始工作。我不知道确切的时间,因为这不是一个高优先级的项目,可能发生在AWS ES更新期间,但不确定为什么会出现这种情况。我现在收到以下错误:

{“error”:{“root_cause”:[{“type”:“mapper_parsing_exception”,“reason”:“object mapping for[results]试图将字段[results]解析为对象,但找到了一个具体值”}],“type”:“mapper_parsing_exception”,“reason”:“object mapping for[results]试图将字段[results]解析为对象,但找到了一个具体值”},“status”:400}

我也尝试将数据存储在表中,认为它是由于潜在的数组而中断的,但没有用:

'id' => 1,
'results' => {"finish":1,"other_id":1,"other_data":1}

我不知道还有什么办法能让它重新工作。

编辑:以下是整个模型:

<?php
namespace App\Models;

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


class ResultsModel extends Model
{

    use Searchable;

    protected $indexConfigurator = \App\MyIndexConfiguratorResults::class;

    protected $searchRules = [
        //
    ];

    protected $mapping = [
        'properties' => [
            'results' => [
                'type' => 'nested',
                'properties' => [
                    'finish' => [
                        'type' => 'integer'
                    ],
                    'other_id' => [
                        'type' => 'integer'
                    ],
                    'other_data' => [
                        'type' => 'integer'
                    ]
                ]
            ],
        ]
    ];

    public function searchableAs()
    {
        return 'results_index';
    }

    public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'results' => $this->results
        ];

        return $array;
    }
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'results_table';

}

以下是\App\MyIndexConfiguratorResults::class

<?php

namespace App;

use ScoutElastic\IndexConfigurator;
use ScoutElastic\Migratable;

class MyIndexConfiguratorResults extends IndexConfigurator
{
    use Migratable;

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

这就是让Laravel在每次更新表格时自动更新AWS ES所需的全部内容。对于初始加载,我将使用SSH连接并运行以下命令,让它创建索引。这以及elastic:migrate和表中的任何更新/插入都会产生映射错误。

php工匠弹性:创建索引results_index

共有2个答案

松铭
2023-03-14

阅读文档时,类型字段似乎已被删除。向下滚动至7。我想看看。此外,似乎您需要删除索引并重新添加,以便新地图根据此页面工作。

上官和惬
2023-03-14

终于找到了答案,所以我们将为任何遇到这个问题的人分享解决方案。事实证明这是一个相当简单的解决方案,尽管我不确定它最初是如何工作的,所以这部分仍然令人困惑。

我创建了一个全新的索引,并相应地更新映射,以添加“id”,并从“results”部分删除类型“nested”。(添加“嵌套”类型就是向索引中添加两个“结果”——一个包含所有嵌套数据,另一个只是“对象”。)

protected $mapping = [
        'properties' => [
            'id' => [
                'type' => 'integer'
            ],
            'results' => [
                'properties' => [
                    'finish' => [
                        'type' => 'integer'
                    ],
                    'other_id' => [
                        'type' => 'integer'
                    ],
                    'other_data' => [
                        'type' => 'integer'
                    ]
                ]
            ],
        ]
    ];

然后,我简单地将json_decode添加到toSearchableArray()函数中,如下所示:

public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'results' => json_decode($this->results, true)
        ];

        return $array;
    }

瞧。它成功地创建了索引,并以我可以查询嵌套对象的方式导入了数据。

 类似资料:
  • 我犯了一个错误,比如: 我知道在堆栈溢出中已经出现了一些类似的问题,但解决方案对我来说并不适用。请您检查一下我的实体,以便找出到底是什么导致了这个问题? 使用者 组 角色 控制器方法 痕迹 /vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(2607):教义\ORM\实用程序\标识符Flattener- 解决了的! 该问题是由重新定义的方法引起

  • 我在Spring绘制地图时遇到了麻烦。我有一个Spring web项目,有用户和数据库。我得到了这个网站。xml: 今年Spring: 这是我的控制器: 我想把所有的请求映射到网址“http://localhost:8080/CRUDWebAppMavenized/users”将打开users.jsp.但我总是只看到错误页面。 IDE告诉我: 警告:org.springframework.web.

  • 我一直试图通过一个名为Guardian的中间类映射两个用户之间的一些“OneToOne”关系。当我试图检索一个用户(和他的监护人)时,从Glassfish(Open edition V4.0)返回一个内部服务器错误。但是,日志中没有显示任何类型的堆栈跟踪或任何错误。我怀疑问题是我在JPA类中的映射。 启动服务器时,我得到两个与Guardian类有关的警告,但我并不真正理解: 警告:映射到元素[me

  • 我使用Angular2β与angular2材料alpha.3他们是兼容的,但我有映射问题。 在我的公开/索引中。我有这个系统设置 但是在我的一个组件中,当我尝试导入并将其添加到指令中以在模板中使用时,如下所示: 我得到这个错误: angular2-polyfills.js:127GEThttp://localhost:8080/node_modules/@angular2-材质/输入404(未找到

  • 我使用DTO和modelMapper是为了不让某些字段可见。我有一个类别实体,可以有子类别 创建类别时,我使用模型: 在此模型中,我希望parentCategoryKeyId与父对象的categoryKeyId匹配。 例如,如果我创建了一个“顶级”类别: 它返回给我: 当我这样做时: 在我的控制器中,我将其余对象传递给DTO层,该层调用服务: 我的类别是基本的POJO: 为我服务: 我的问题是,我