【问题标题】:How to execute a bulk ElasticSearch operation from an AppSync resolver?如何从 AppSync 解析器执行批量 ElasticSearch 操作?
【发布时间】:2021-02-13 09:08:44
【问题描述】:

我正在尝试通过 VTL AppSync 解析器对 ElasticSearch 索引执行批量操作。

特别是这个突变:

input CreateTopicsInput {
  language: String!
  texts: [String!]!
}

type Mutation {
  createTopics(input: CreateTopicsInput!): [Topic!]
}

我创建了以下解析器: Mutation.createTopics.req.vtl

#set( $body = "" )
#set( $q = '"' )
#foreach( $text in $ctx.args.input.texts )
  #set( $body = $body.concat("{ ${q}index${q}: { ${q}_id${q}: ${q}${text}${q} } }
") )
  #set( $body = $body.concat("{ ${q}text${q}: ${q}$text${q}, ${q}suggest${q}: { ${q}input${q}: ${q}$text${q} } }
") )
#end
{
  "version": "2017-02-28",
  "operation": "POST",
  "path": "/topic-${ctx.args.input.language}/doc/_bulk",
  "params": {
    "headers" : [ { "Content-Type" : "application/x-ndjson" } ],
    "body": "$body"
  }
}

例如,当使用此数据执行时:

mutation CreateTopic {
  createTopics(input: {
    language: "en",
    texts: [ "COVID", "Election" ]}) {
    text
  }
}

似乎输出了正确的调用:

{
  "version": "2017-02-28",
  "operation": "POST",
  "path": "/topic-en/doc/_bulk",
  "params": {
    "headers" : [ { "Content-Type" : "application/x-ndjson" } ],
    "body": "{ "index": { "_id": "COVID" }
{ "text": "COVID" }
{ "index": { "_id": "Election" }
{ "text": "Election" }
"
  }
}

但它不起作用。具体来说,它会抛出:

{
  "data": {
    "createTopics": null
  },
  "errors": [
    {
      "path": [
        "createTopics"
      ],
      "data": null,
      "errorType": "MappingTemplate",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Unexpected character ('i' (code 105)): was expecting comma to separate Object entries\n at [Source: (String)\"{\n  \"version\": \"2017-02-28\",\n  \"operation\": \"POST\",\n  \"path\": \"/topic-en/doc/_bulk\",\n  \"params\": {\n    \"headers\" : { \"Content-Type\" : \"application/x-ndjson\" },\n    \"body\": \"{ \"index\": { \"_id\": \"CODID\" } }\n{ \"text\": \"CODID\", \"suggest\": { \"input\": \"CODID\" } }\n{ \"index\": { \"_id\": \"Election\" } }\n{ \"text\": \"Election\", \"suggest\": { \"input\": \"Election\" } }\n\"\n  }\n}\n\"; line: 7, column: 18]"
    }
  ]
}

有什么想法吗?

【问题讨论】:

    标签: elasticsearch aws-appsync resolver vtl


    【解决方案1】:

    我玩了一下,发现你需要

    • 引用你的双引号
    • 全部写在一行中,除以“\n”
    • 该行的最后一部分需要再次成为“\n”

    例如:

    {
     "version": "2018-05-29",
     "method": "POST",
     "resourcePath": "/_msearch/template",
     "params": {
       "headers": {
         "Content-Type": "application/x-ndjson"
       },
       "body": "{ \"index\": { \"_id": \"COVID\" }\n{ \"text\": \"COVID\" }\n"
     }
    }
    

    当然,这不是很令人信服,对于您的用例,这可能会更好:

    #set($ndjson = [])
    $util.qr($ndjson.add({ "index": "COVID" }))
    $util.qr($ndjson.add({ "text": "COVID", "Param2": "vaccine" } }))
     
     
    {
     "version": "2018-05-29",
     "method": "POST",
     "resourcePath": "/_msearch/template",
     "params": {
       "headers": {
         "Content-Type": "application/x-ndjson"
       },
       "body": "#foreach ($line in $ndjson)$util.escapeJavaScript($util.toJson($line))\n#end"
     }
    }
    

    (可能)有问题的部分可能是 JavaScript 转义。不确定您的数据是什么样子,但可能会根据需要产生更多引用的数据。

    P.s:我将我的实现切换到最后提到的示例,它适用于多重搜索。

    【讨论】:

      猜你喜欢
      • 2019-02-03
      • 2017-05-17
      • 1970-01-01
      • 2012-03-03
      • 2014-08-10
      • 1970-01-01
      • 2019-09-01
      • 2015-02-15
      • 1970-01-01
      相关资源
      最近更新 更多