在我的laravel 5.7应用程序中,我使用Elasticsearch,并且具有批量功能以相关的表决项来填充我的投票。
问题是我在出现错误时无法添加相关的表决项目数组:
18:00
在方法(错误行已取消注释并标记):
{"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"object mapping for [vote_items] tried to parse field [null] as object, but found a concrete value"}],"type":"mapper_parsing_exception","reason":"object mapping for [vote_items] tried to parse field [null] as object, but found a concrete value"},"status":400}
如果我取消注释行:
public static function bulkVotesToElastic()
{
$elastic = app(\App\Elastic\Elastic::class);
$elasticsearch_root_index = config('app.elasticsearch_root_index');
$elasticsearch_type = with(new Vote)->getElasticsearchType();
Vote::chunk(100, function ($Votes) use ($elastic, $elasticsearch_root_index, $elasticsearch_type) {
foreach ($Votes as $nextVote) {
if ($nextVote->status!= 'A') continue; // only active votes must be saved in elasticsearch
$voteCategory= $nextVote->voteCategory;
if (empty($voteCategory)) continue; // only votes with valid category must be saved in elasticsearch
if ( !$voteCategory->active ) continue; // only votes with active category must be saved in elasticsearch
$voteItems = VoteItem
::getByVote($nextVote->id)
->orderBy('ordering', 'asc')
->get();
$relatedVoteItemsList= [];
foreach ($voteItems as $nextVoteItem) {
$relatedVoteItemsList[]= $nextVoteItem->name; // THIS LINE RAISE ERROR!
// $relatedVoteItemsList[]= [ $nextVoteItem->name ]; // THIS LINE RAISE ERROR TOO!
// $relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ]; // THIS LINE DOES NOT RAISE ERROR!
}
$elastic->index([
'index' => $elasticsearch_root_index,
'type' => $elasticsearch_type,
'id' => $nextVote->id,
'body' => [
'id' => $nextVote->id,
'slug' => $nextVote->slug,
'name' => $nextVote->name,
'description' => $nextVote->description,
'created_at' => $nextVote->created_at,
'vote_items' => $relatedVoteItemsList,
'category_id' => $voteCategory->id,
'category' => [
'name' => $voteCategory->name,
'slug' => $voteCategory->slug,
'created_at' => $voteCategory->created_at,
],
]
]);
}
});
}
并在上方两行添加注释,然后批量显示即可,但是我的搜索条件不适用于vote_items
// $relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ]; // THIS LINE DOES NOT RAISE ERROR!
我不知道哪种语法有效?
更新#2: 查看提供的文档链接,我看到:
$elasticQuery = [
"bool" => [
'must' => [
[
"multi_match" => [
"query" => $text,
"type" => "cross_fields",
"fields" => [
"name^4",
"description",
"vote_items^2"
]
],
],
],
]
];
我想保存数据必须指出一些数据是嵌套的。
我将批量功能重新制作为:
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
}
但要查看映射:
foreach ($Votes as $nextVote) {
if ($nextVote->status!= 'A') continue; // only active votes must be saved in elasticsearch
$voteCategory= $nextVote->voteCategory;
if (empty($voteCategory)) continue; // only votes with valid category must be saved in elasticsearch
if ( !$voteCategory->active ) continue; // only votes with active category must be saved in elasticsearch
$voteItems = VoteItem
::getByVote($nextVote->id)
->orderBy('ordering', 'asc')
->get();
$relatedVoteItemsList= [];
foreach ($voteItems as $nextVoteItem) {
$relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ]; // VALID STRUCTURE ?
}
$elastic->index([
'index' => $elasticsearch_root_index,
'type' => $elasticsearch_type,
'id' => $nextVote->id,
'body' => [
'id' => $nextVote->id,
'slug' => $nextVote->slug,
'name' => $nextVote->name,
'description' => $nextVote->description,
'created_at' => $nextVote->created_at,
'vote_items' => $relatedVoteItemsList,
'category_id' => $voteCategory->id,
'category' => [
'name' => $voteCategory->name,
'slug' => $voteCategory->slug,
'created_at' => $voteCategory->created_at,
],
]
]);
我看不到钢笔标记为嵌套的,但查看样本我必须支持它? 哪种方法可以正确地写入我的数据,使表决对象被标记为嵌套?
谢谢!
答案 0 :(得分:1)
似乎vote_items
是嵌套类型字段。像这样:
{
"vote_items" : {
"type": "nested",
"properties": {
"vote_item_name": {
"type": "keyword"
}
}
}
}
这是以下原因起作用的原因:
$relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ];
要查询嵌套字段,您需要使用以下语法:
{
"query": {
"nested": {
"path": "vote_items",
"query": {
"bool": {
"must": [
{
"match": {
"vote_items.vote_item_name": "xyz"
}
}
]
}
}
}
}
}
请注意,nested
块具有path
(提及要查询的嵌套类型字段),query
(要在嵌套对象上运行的查询)。另请注意,字段名称应为完全限定名称,即<nested_field_name>.<property>
,在这种情况下为vote_items.vote_item_name
。
注意:上面的查询是如何使用索引映射的字段查询嵌套字段的示例。请根据您的需要进行修改。
有关如何查询nested fields的更多信息,请参见here。
答案 1 :(得分:1)
您看到这个https://github.com/elasticquent/Elasticquent插件了吗? 它具有索引和映射示例,例如:
protected $mappingProperties = array(
'title' => array(
'type' => 'string',
'analyzer' => 'standard'
)
);
如果您想根据自己的映射属性设置模型的类型映射,可以使用:
Book :: putMapping($ ignoreConflicts = true);