2015-10-29 20 views
0

我希望能够在我的ES索引中存储json对象。下面是我想要存储的例子(这个序列化模型,发送到ES请求主体):Yii2 Elasticsearch扩展 - 我如何处理类型映射?

"{"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

不过,我似乎还没有找到一个在模型内部提供该映射的方式。该扩展的文档没有提到任何有关它的信息。 所以,我的问题是:我是否需要它,如果我这样做,如何?

欣赏所有反馈。

回答

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中创建表。

+0

谢谢。虽然我明白了,但这证实了我的想法。顺便说一下,还有一个问题:我可以以某种方式在ES activequery中定义排序吗?还没有找到方法。 – nainy

+1

您只需将一个数组传递给'orderBy()'。查看确切的结构[这里](https://www.elastic。但是通常类似'[[“name”=>“desc”],[“date”=>“asc”]]'' 。 – Beowulfenator

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"], 

       ], 
      ], 
     ]); 
    } 
} 

后来,你只需要调用此方法要应用新的映射任何时间的方法。