首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用相关项填充弹性搜索时出错

用相关项填充弹性搜索时出错
EN

Stack Overflow用户
提问于 2018-11-24 07:44:26
回答 2查看 501关注 0票数 0

在我的Laravel5.7应用程序中,我使用Elasticsearch,我有大量的功能来填充我的选票与相关的vote_items。

问题是,当我得到错误时,我无法添加相关的vote_items数组:

代码语言:javascript
复制
{"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}

at方法(错误行取消注释并标记):

代码语言:javascript
复制
    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,
                        ],
                    ]
                ]);
            }
        });
    }

如果我取消评论行:

代码语言:javascript
复制
//                    $relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ];   // THIS LINE DOES NOT RAISE ERROR!

上面的注释2行工作正常,但我的搜索条件不适用于vote_items。

代码语言:javascript
复制
$elasticQuery = [
    "bool" => [
        'must' => [
            [
                "multi_match" => [
                    "query"  => $text,
                    "type"   => "cross_fields",
                    "fields" => [
                        "name^4",
                        "description",
                        "vote_items^2"
                    ]
                ],
            ],
        ],
    ]
];

我不知道哪种语法是有效的?

更新的# 2:查看提供的docs链接,我看到:

代码语言:javascript
复制
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "user": {
          "type": "nested" 
        }
      }
    }
  }
}

我假设保存我的数据,我必须指出有些数据是嵌套的。

我把我的大容量功能改造成:

代码语言:javascript
复制
    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,
                ],
            ]
        ]);

但是看一下地图:

代码语言:javascript
复制
http://localhost:9200/_mapping :
"select_vote": {
"mappings": {
"vote": {
"properties": {
"category": {
"properties": {
"created_at": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"slug": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"category_id": {
"type": "long"
},
"created_at": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"creator_id": {
"type": "long"
},
"description": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "long"
},
"image": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"is_homepage": {
"type": "long"
},
"is_quiz": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"ordering": {
"type": "long"
},
"slug": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"status": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"vote_category_id": {
"type": "long"
},
"vote_items": {
"properties": {
"is_correct": {
"type": "long"
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"vote_item_id": {
"type": "long"
},
"vote_item_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"vote_items": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
}

我没有看到标记为嵌套的vote_items,但是看看示例,我认为它必须吗?哪种方法可以正确地编写vote_items标记为嵌套的数据?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-24 09:06:14

vote_items似乎是嵌套类型字段。就像这样:

代码语言:javascript
复制
{
  "vote_items" : {
     "type": "nested",
     "properties": {
        "vote_item_name": {
           "type": "keyword"
        }
     }
  }
}

这就是为什么要做以下工作:

$relatedVoteItemsList[]= [ 'vote_item_name' => $nextVoteItem->name ];

要查询嵌套字段,需要使用以下语法:

代码语言:javascript
复制
{
  "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

注意:上面的查询是如何使用索引映射的字段查询嵌套字段的示例。请根据您的需要修改。

有关如何查询嵌套字段的更多信息,请参见这里

票数 1
EN

Stack Overflow用户

发布于 2018-11-28 11:47:45

你看到这个https://github.com/elasticquent/Elasticquent插件了吗?它有索引和映射示例,如:

代码语言:javascript
复制
protected $mappingProperties = array(
   'title' => array(
        'type' => 'string',
        'analyzer' => 'standard'
    )
);

如果希望根据映射属性设置模型的类型映射,可以使用:

书::putMapping($ignoreConflicts= true);

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53456204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档