如何解决对于弹性搜索索引,如何获取数组字段长度大于0的文档?
在弹性搜索索引中,如何获取数组字段长度大于0的文档?
我尝试使用多种语法,但没有任何突破。我在所有语法中都遇到了相同的错误。
获取http:// {{host}}:{{elasticSearchPort}} / student_details / _search
语法1:
{
"query": {
"bool": {
"filter": {
"script": {
"script": {
"source": "doc['enrolledCourses'].values.length > 0","lang": "painless"
}
}
}
}
}
}
错误:
"caused_by": {
"type": "illegal_argument_exception","reason": "No field found for [enrolledCourses] in mapping with types []"
}
语法2:
{
"query": {
"bool": {
"filter": {
"script": {
"script": {
"source": "doc['enrolledCourses'].values.size() > 0","reason": "No field found for [enrolledCourses] in mapping with types []"
}
语法3:
{
"query": {
"bool": {
"filter" : {
"script" : {
"script" : "doc['enrolledCourses'].values.size() > 0"
}
}
}
}
}
错误:
"caused_by": {
"type": "illegal_argument_exception","reason": "No field found for [enrolledCourses] in mapping with types []"
}
语法4:
{
"query": {
"bool": {
"filter" : {
"script" : {
"script" : "doc['enrolledCourses'].values.length > 0"
}
}
}
}
}
错误:
"caused_by": {
"type": "illegal_argument_exception","reason": "No field found for [enrolledCourses] in mapping with types []"
}
请帮助我解决这个问题。
解决方法
我不知道您运行的是哪个版本的Elastic,然后我的所有测试都将在最新的7.9.0版本的Elasticsearch上运行。
我将使用轻松的脚本编写脚本。
我对文档进行了索引测试:
PUT test/_doc/1
{
"name": "Vasia","enrolledCourses" : ["test1","test2"]
}
PUT test/_doc/2
{
"name": "Petya"
}
如何查看一个文档包含enrolledCourses
字段,而第二个文档不包含。
在轻松的情况下,您不需要使用值字段,而可以直接获取长度,这是根据painless documentation得出的。然后,我在脚本中跳过使用values
运算符:
GET test/_search
{
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source": "doc['enrolledCourses'].length > 0","lang": "painless"
}
}
}
]
}
}
}
运行后,我收到两个不同的错误:
{
"type" : "script_exception","reason" : "runtime error","script_stack" : [
"org.elasticsearch.index.mapper.TextFieldMapper$TextFieldType.fielddataBuilder(TextFieldMapper.java:757)","org.elasticsearch.index.fielddata.IndexFieldDataService.getForField(IndexFieldDataService.java:116)","org.elasticsearch.index.query.QueryShardContext.lambda$lookup$0(QueryShardContext.java:331)","org.elasticsearch.search.lookup.LeafDocLookup$1.run(LeafDocLookup.java:97)","org.elasticsearch.search.lookup.LeafDocLookup$1.run(LeafDocLookup.java:94)","java.base/java.security.AccessController.doPrivileged(AccessController.java:312)","org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:94)","org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:41)","doc['enrolledCourses'].length > 0"," ^---- HERE"
]
}
and
{
"type" : "illegal_argument_exception","reason" : "Text fields are not optimised for operations that require per-document field data like aggregations and sorting,so these operations are disabled by default. Please use a keyword field instead. Alternatively,set fielddata=true on [enrolledCourses] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
}
两个错误都很明显。首先是不存在该字段的文档,其次是因为Elasticsearch将字符串数组字段索引为默认映射类型text
。
通过将enrolledCourses
字段映射为keyword
,很容易解决这两种情况。
在第一种情况下,映射将始终提供空白字段,而在第二种关键字中,则允许运行fielddata属性。
PUT test
{
"settings": {
"number_of_replicas": 0
},"mappings": {
"properties": {
"name": {
"type": "keyword"
},"enrolledCourses": {
"type": "keyword"
}
}
}
}
现在,我将收到查询的正确答案:
{
"took" : 0,"timed_out" : false,"_shards" : {
"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0
},"hits" : {
"total" : {
"value" : 1,"relation" : "eq"
},"max_score" : 0.0,"hits" : [
{
"_index" : "test","_type" : "_doc","_id" : "1","_score" : 0.0,"_source" : {
"name" : "Vasia","enrolledCourses" : [
"test1","test2"
]
}
}
]
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。