【问题标题】:Yii2 Elasticsearch extension - how do I handle type mapping?Yii2 Elasticsearch 扩展 - 我如何处理类型映射?
【发布时间】:2016-01-29 12:23:03
【问题描述】:

我希望能够在我的 ES 索引中存储一个 json 对象。这是我尝试存储的示例(这是一个序列化模型,一个发送到 ES 的请求正文):

"{"id":218,"name":"Test2","category_id":1,"address":"Pushkin street","phone":null,"site":null,"location":{"lat":64,"lon":70},"city":"Heaven","description":"Super company","tags":["#test1","#test2"]}"

当我尝试存储它时(当然是通过扩展),这是 ES 返回的错误:

"{"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"failed to parse [location]"}],"type":"mapper_parsing_exception","reason":"failed to parse [location]","caused_by":{"type":"illegal_argument_exception","reason":"unknown property [lat]"}},"status":400}"

如果没有特定的类型映射,我似乎无法这样做,就像在文档中一样: https://www.elastic.co/guide/en/elasticsearch/reference/1.4/mapping-object-type.html

但是,我似乎没有找到在模型中提供该映射的方法。扩展的文档并没有真正说明它。 所以,我的问题是:我是否需要它,如果需要,如何?

感谢所有反馈。

【问题讨论】:

    标签: php json elasticsearch yii2 yii2-extension


    【解决方案1】:

    我假设你的模型是\yii\elasticsearch\ActiveRecord。你需要描述它的属性:

    public function attributes()
    {
      return [
        'name',
        'category_id',
        'address',
        'phone',
        'site',
        'location',
        'city',
        'description',
        'tags'
      ];
    }
    

    别忘了配置index()type()。在以下示例中,typemy_address

    然后你需要create an indexproper field mapping。您的映射应该如下所示:

    "mappings" : {
      "my_address" : {
        "properties" : {
          "name" : { "type" : "string"},
          "category_id" : { "type" : "integer"},
          "address" : { "type" : "string"},
          "phone" : { "type" : "string"},
          "site" : { "type" : "string"},
          "location" : { "type" : "geo_point"},
          "city" : { "type" : "string"},
          "description" : { "type" : "string"},
          "tags" : { "type" : "string"}
        }
      }
    }
    

    注意三点:

    1. 位置类型为geo_point
    2. 标签被声明为string。这也将允许它们成为字符串数组。
    3. 我没有包含 id 字段。如果它是唯一的,我建议您将 yii 模型的 id 设置为必要的值($model->primaryKey = '123')。否则,您的 ES 模型会将其内部 id 设置为 AVDXmfJ3Ou7LzqD1DDMj 之类的东西,并且还有一个不太方便的 id 字段。

    我鼓励您仔细查看映射 - 在配置如何准确分析字符串时,它们非常重要。

    更新:您并没有真正描述模型中任何地方的映射。在迁移中执行 - 类似于在 SQL 中创建表。

    【讨论】:

    • 谢谢。虽然我想通了,但这证实了我的想法。顺便说一句,还有一个问题:我可以在 ES activequery 中以某种方式定义排序吗?还没找到方法。
    • 您只需将数组传递给orderBy()。查找确切的结构 here,但通常类似于 [["name" => "desc"], ["date" => "asc"]]
    【解决方案2】:

    如果你使用 ElasticSearch ActiveRecord,你可以定义一个 setupMapping 方法

    Class BookIndex extends yii\elasticsearch\ActiveRecord
    {
        /**
         * sets up the index for this record
         *
         */
        public static function setUpMapping()
        {
            $db = static::getDb();
    
            //in case you are not using elasticsearch ActiveRecord so current class extends database ActiveRecord yii/db/activeRecord
            // $db = yii\elasticsearch\ActiveRecord::getDb();
    
            $command = $db->createCommand();
    
            /*
             * you can delete the current mapping for fresh mapping but this not recommended and can be dangrous.
             */
    
            // $command->deleteMapping(static::index(), static::type());
    
            $command->setMapping(static::index(), static::type(), [
                static::type() => [
                    // "_id" => ["path" => "id", "store" => "yes"],
                    "properties" => [
                        'name'           => ["type" => "string"],
                        'author_name'    => ["type" => "string"],
                        'publisher_name' => ["type" => "string"],
                        'created_at'     => ["type" => "long"],
                        'updated_at'     => ["type" => "long"],
                        'status'         => ["type" => "long"],
    
                    ],
                ],
            ]);
        }
    }
    

    稍后您只需在想要应用新映射的任何时候调用此方法。

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2013-01-09
      相关资源
      最近更新 更多