Yii2 Elasticsearch 扩展——如何处理类型映射?
Yii2 Elasticsearch extension - how do I handle type mapping?
我希望能够在我的 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 returns:
的错误
"{"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
但是,我似乎找不到在模型内部提供该映射的方法。扩展的文档并没有真正说明它。
所以,我的问题是:我是否需要它,如果需要,怎么做?
感谢所有反馈。
我假设您的模型是 \yii\elasticsearch\ActiveRecord
。您需要描述其属性:
public function attributes()
{
return [
'name',
'category_id',
'address',
'phone',
'site',
'location',
'city',
'description',
'tags'
];
}
不要忘记配置 index()
和 type()
。在下面的例子中 type
是 my_address
.
然后你需要create an index with proper 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"}
}
}
}
注意三件事:
- 位置类型为
geo_point
。
- 标签声明为
string
。这也将允许它们成为字符串数组。
- 我没有包含 id 字段。如果它是唯一的,我建议您将您的 yii 模型的 id 设置为必要的值 (
$model->primaryKey = '123'
)。否则,您的 ES 模型会将其内部 ID 设置为 AVDXmfJ3Ou7LzqD1DDMj
之类的内容,并且还有一个 id 字段,这不是很方便。
我鼓励您仔细查看映射 - 在配置字符串分析的准确方式时,它们非常重要。
更新:您并没有真正描述模型中任何地方的映射。在迁移中执行 - 类似于在 SQL.
中创建表
如果您使用 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"],
],
],
]);
}
}
稍后您只需在需要应用新映射的任何时候调用此方法即可。
我希望能够在我的 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 returns:
的错误"{"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
但是,我似乎找不到在模型内部提供该映射的方法。扩展的文档并没有真正说明它。 所以,我的问题是:我是否需要它,如果需要,怎么做?
感谢所有反馈。
我假设您的模型是 \yii\elasticsearch\ActiveRecord
。您需要描述其属性:
public function attributes()
{
return [
'name',
'category_id',
'address',
'phone',
'site',
'location',
'city',
'description',
'tags'
];
}
不要忘记配置 index()
和 type()
。在下面的例子中 type
是 my_address
.
然后你需要create an index with proper 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"}
}
}
}
注意三件事:
- 位置类型为
geo_point
。 - 标签声明为
string
。这也将允许它们成为字符串数组。 - 我没有包含 id 字段。如果它是唯一的,我建议您将您的 yii 模型的 id 设置为必要的值 (
$model->primaryKey = '123'
)。否则,您的 ES 模型会将其内部 ID 设置为AVDXmfJ3Ou7LzqD1DDMj
之类的内容,并且还有一个 id 字段,这不是很方便。
我鼓励您仔细查看映射 - 在配置字符串分析的准确方式时,它们非常重要。
更新:您并没有真正描述模型中任何地方的映射。在迁移中执行 - 类似于在 SQL.
中创建表如果您使用 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"],
],
],
]);
}
}
稍后您只需在需要应用新映射的任何时候调用此方法即可。