【问题标题】:Elasticsearch - Missing Field Value For Nested Field - Function Score Query | v7.10.2Elasticsearch - 嵌套字段的缺失字段值 - 函数得分查询 | v7.10.2
【发布时间】:2022-01-17 01:25:51
【问题描述】:

我已经在 ES 组上发布了这个,但我没有得到任何回应,所以把它发布在 SO 上。链接https://discuss.elastic.co/t/missing-field-value-for-nested-field-function-score-query-v7-10-2/291365

我已经尝试了很长时间但是嵌套字段值在计算分数时总是说缺少字段值。

映射:

{
  "doctor_idx" : {
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "keyword",
          "index" : false,
          "doc_values" : false
        },
        "service" : {
          "type" : "nested",
          "properties" : {
            "_class" : {
              "type" : "keyword",
              "index" : false,
              "doc_values" : false
            },
            "serviceTypeEarliestAvailability" : {
              "type" : "nested",
              "properties" : {
                "_class" : {
                  "type" : "keyword",
                  "index" : false,
                  "doc_values" : false
                },
                "earliestAvailableDateTimeByType" : {
                  "type" : "date",
                  "format" : "date_hour_minute_second"
                },
                "serviceType" : {
                  "type" : "text"
                },
                "servicesMedium" : {
                  "type" : "keyword"
                }
              }
            }
          }
        }
      }
    }
  }
}

为简单起见,我只保留了一条记录。记录一瞥

"serviceTypeEarliestAvailability" : [
              {
                "serviceType" : "Service Type",
                "earliestAvailableDateTimeByType" : "2021-12-09T19:39:16",
                "servicesMedium" : [
                  "MED1",
                  "MED2",
                  "MED3",
                  "MED4"
                ]
              }
            ],

以下查询给出:“文档没有字段值!使用 doc[].size()==0 检查文档是否缺少字段!”

我尝试使用field_value_factor 而不是script_score,但这是同样的问题,它抱怨缺少字段值。

查询 1:使用 script_score

GET /doctor_idx/_search
{
  "explain": true,
  "query": {
    "nested": {
      "path": "service",
      "query": {
        "nested": {
          "score_mode": "max",
          "path": "service.serviceTypeEarliestAvailability",
          "query": {
            "function_score": {
              "query": {
                "match_all": {
                  "boost": 1
                }
              },
              "functions": [
                {
                  "filter": {
                    "match": {
                      "service.serviceTypeEarliestAvailability.serviceType": "type" // no complaints about this
                    }
                  },
                  "weight": 10
                },
                {
                  "script_score": {
                    "script": {
          "source":     "(doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value.getMillis())"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

查询 2:field_value_factor

GET /doctor_idx/_search
{
  "explain": true,
  "query": {
    "nested": {
      "path": "service",
      "query": {
        "nested": {
          "score_mode": "max",
          "path": "service.serviceTypeEarliestAvailability",
          "query": {
            "function_score": {
              "query": {
                "match_all": {
                  "boost": 1
                }
              },
              "functions": [
                {
                  "filter": {
                    "match": {
                      "service.serviceTypeEarliestAvailability.serviceType": "type" 
                    }
                  },
                  "weight": 10
                },
                {
                  "field_value_factor": {
                    "field": "service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

查询 1 的 ES 错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "runtime error",
        "script_stack" : [
          "org.elasticsearch.index.fielddata.ScriptDocValues$Dates.get(ScriptDocValues.java:160)",
          "org.elasticsearch.index.fielddata.ScriptDocValues$Dates.getValue(ScriptDocValues.java:154)",
          "(doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value.getMillis())",
          "                                                                               ^---- HERE"
        ],
        "script" : "(doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value.getMillis())",
        "lang" : "painless",
        "position" : {
          "offset" : 79,
          "start" : 0,
          "end" : 98
        }
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "doctor_idx",
        "node" : "mvh5k24dQPqM-d7JVeNomQ",
        "reason" : {
          "type" : "script_exception",
          "reason" : "runtime error",
          "script_stack" : [
            "org.elasticsearch.index.fielddata.ScriptDocValues$Dates.get(ScriptDocValues.java:160)",
            "org.elasticsearch.index.fielddata.ScriptDocValues$Dates.getValue(ScriptDocValues.java:154)",
            "(doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value.getMillis())",
            "                                                                               ^---- HERE"
          ],
          "script" : "(doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value.getMillis())",
          "lang" : "painless",
          "position" : {
            "offset" : 79,
            "start" : 0,
            "end" : 98
          },
          "caused_by" : {
            "type" : "illegal_state_exception",
            "reason" : "A document doesn't have a value for a field! Use doc[<field>].size()==0 to check if a document is missing a field!"
          }
        }
      }
    ]
  },
  "status" : 400
}

查询 2 的 ES 错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "exception",
        "reason" : "Missing value for field [service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType]"
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "doctor_idx",
        "node" : "mvh5k24dQPqM-d7JVeNomQ",
        "reason" : {
          "type" : "exception",
          "reason" : "Missing value for field [service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType]"
        }
      }
    ]
  },
  "status" : 500
}

我在ES里唯一的记录

{
  "took" : 32,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "doctor_idx",
        "_type" : "_doc",
        "_id" : "xM20oH0Bmp1zsT0w8pQe",
        "_score" : 1.0,
        "_source" : {
          "_class" : "com.insig.clinic_apps.services_server.booking.dao.DoctorSchema",
          "id" : "xM20oH0Bmp1zsT0w8pQe",
          "metadata" : {
            "doctorId" : "xhnz2lGvXxelWyVekz82c2v6Srb2",
            "fullName" : "Dave Insig Email Test",
            "credentials" : [
              "MD"
            ],
            "languagesSpoken" : [
              "EN",
              "NOT_DEFINED"
            ],
            "specialitiesServed" : [ ],
            "city" : "VAUGHAN",
            "provincesPermitted" : [ ],
            "province" : "ON",
            "country" : "CANADA"
          },
          "service" : {
            "servicesMedium" : [
              "IN_CLINIC",
              "VIDEO",
              "MESSAGING",
              "PHONE"
            ],
            "servicesTypeDuration" : [
              {
                "serviceType" : "Acne Symptoms",
                "duration" : 5,
                "servicesMedium" : [
                  "IN_CLINIC",
                  "MESSAGING",
                  "PHONE",
                  "VIDEO"
                ]
              }
            ],
            "serviceTypeEarliestAvailability" : [
              {
                "serviceType" : "Acne Symptoms",
                "earliestAvailableDateTimeByType" : "2021-12-09T19:39:16",
                "servicesMedium" : [
                  "IN_CLINIC",
                  "MESSAGING",
                  "PHONE",
                  "VIDEO"
                ]
              }
            ],
            "bufferTimeForNextAvailability" : 0
          },
          "earliestAvailableDateTime" : "2021-12-09T19:39:16",
          "patientRating" : 4.384481,
          "onTimeRating" : 3.171053
        }
      }
    ]
  }
}

【问题讨论】:

  • 您好,您能粘贴实际的错误日志,并提供完整的示例文档吗?它将有助于调试^^
  • @Paulo 看看
  • 对于 Query1 ...您在错误中有一个解决方案建议,您似乎有一些文档对 earliestAvailableDateTimeByType 没有价值。对于 Query2,我不确定。但我很想有一个完整的示例文档来帮助我尝试
  • 我只添加了一个文档,并确保 earliestAvailableDateTimeByType 在其中有价值。因此,它具有价值,但 ES 给了我这个错误。 IDK 为什么
  • @Paulo 我什至添加了 ES 的结果。看看吧。

标签: elasticsearch


【解决方案1】:

/!\部分解/!\

查询 1

当我试图执行您的查询时,我收到了这个错误:

{
    "caused_by" : {
        "type" : "illegal_argument_exception",
        "reason" : "dynamic method [org.elasticsearch.script.JodaCompatibleZonedDateTime, toEpochMilli/0] not found"
    }
}

所以我对您的查询.toInstant().toEpochMilli()做了一点改动

GET /so_custom_score/_search
{
  "explain": true,
  "query": {
    "nested": {
      "path": "service",
      "query": {
        "nested": {
          "score_mode": "max",
          "path": "service.serviceTypeEarliestAvailability",
          "query": {
            "function_score": {
              "query": {
                "match_all": {
                  "boost": 1
                }
              },
              "functions": [
                {
                  "filter": {
                    "match": {
                      "service.serviceTypeEarliestAvailability.serviceType": "type"
                    }
                  },
                  "weight": 10
                },
                {
                  "script_score": {
                    "script": {
                      "source": """
                      def availability = doc['service.serviceTypeEarliestAvailability.earliestAvailableDateTimeByType'].value;
                      return availability.toInstant().toEpochMilli();
                      """
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

【讨论】:

    【解决方案2】:

    好吧,在这里浪费了很多时间,并认为查询没有问题。当我尝试获取查询的解释时,Elasticsearch v7.10.2 出现问题。

    没有explain 参数,它工作得非常好。

    at org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction$1.explainScore(FieldValueFactorFunction.java:103) ~[elasticsearch-7.10.2.jar:7.10.2]

    PS:OG 问题中的一位 cmets 提到,最新的 Elasticsearch v7.15 即使使用 explain 参数也能正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-10
      • 2020-09-04
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多