Yii2 Elasticsearch扩展 - 如何处理类型映射?

时间:2015-10-29 11:23:50

标签: php json elasticsearch yii2 yii2-extension

我希望能够在我的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

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

感谢所有反馈。

2 个答案:

答案 0 :(得分:1)

我假设您的模型是<?php $query = new WP_Query('cat='.$cat[0]->cat_ID); while ($query->have_posts()) : $query->the_post();?> <li <?php echo get_the_ID() == get_query_var('p') ? 'class="current-menu-item"' : '';?>><a href="<?php echo the_permalink();?>"><?php echo get_the_title();?></a></li> <?php endwhile;?> 。您需要描述其属性:

\yii\elasticsearch\ActiveRecord

不要忘记配置public function attributes() { return [ 'name', 'category_id', 'address', 'phone', 'site', 'location', 'city', 'description', 'tags' ]; } index()。在以下示例中,type()type

然后您需要create an index proper field mapping。这是您的映射应该是什么样的:

my_address

注意三件事:

  1. 位置属于"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"} } } }
  2. 标签声明为geo_point。这也将允许它们成为字符串数组。
  3. 我没有包含id字段。如果它是唯一的,我建议你只需将你的yii模型的id设置为必要的值(string)。否则,您的ES模型的内部ID将设置为$model->primaryKey = '123',并且还有一个不太方便的id字段。
  4. 我建议您仔细查看映射 - 在配置字符串的确切分析时,它们非常重要。

    更新:您并未真正描述模型中任何位置的映射。在迁移中执行此操作 - 类似于在SQL中创建表。

答案 1 :(得分:1)

如果您使用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"],

                ],
            ],
        ]);
    }
}

稍后您只需要在应用新映射时调用此方法。