Elasticsearch中的嵌套文档

Tro*_*roy 23 elasticsearch

我正在写一个资产管理应用程序.它允许用户通过向资产添加html控件(如文本字段,选择菜单等)来存储任意资产属性.然后,该属性的JSON表示将成为存储在couchdb中的资产JSON文档的一部分.资产在couchdb中具有以下结构:

{
   "_id": "9399fb27448b1e5dfdca0181620418d4",
   "_rev": "12-fa50eae8b50f745f9852e9fab30ef5d9",
   "type": "asset",
   "attributes": [
       {
           "id": "9399fb27448b1e5dfdca01816203d609",
           "type": "text",
           "heading": "Brand",
           "data": "",
           "requiredBySystem": true
       },
       {
           "id": "9399fb27448b1e5dfdca01816203e68e",
           "type": "userSelectMenu",
           "heading": "Assigned To",
           "data": "",
           "requiredBySystem": true
       },
       {
           "id": "9399fb27448b1e5dfdca01816203e9c9",
           "type": "categories",
           "heading": "Categories",
           "data": [
               "0d7e6233e5f48b4f55c5376bf00b1be5",
               "0d7e6233e5f48b4f55c5376bf00d94cf"
           ],
           "requiredBySystem": true
       },
       {
           "id": "9399fb27448b1e5dfdca01816207uy5a",
           "type": "radio",
           "heading": "Radio Buttons",
           "data": [
               {
                   "text": "Button 1",
                   "checked": false
               },
               {
                   "text": "Button 2",
                   "checked": true
               }
           ],
           "requiredBySystem": true
       },
       {
           "id": "9399fb27448b1e5dfdca01816205tgh6",
           "type": "checkboxes",
           "heading": "Checkboxes",
           "data": [
             {
                 "text": "Box 1",
                 "checked": false
             },
             {
                 "text": "Box 2",
                 "checked": true
             }
           ],
           "requiredBySystem": true
       },
       {
           "id": "9399fb27448b1e5dfdca0181620k81gt",
           "type": "select",
           "heading": "Select Menu",
           "data": [
               {
                   "text": "Option 1",
                   "checked": false
               },
               {
                   "text": "Option 2",
                   "checked": true
               }
           ],
           "requiredBySystem": true
       }
   ]
}
Run Code Online (Sandbox Code Playgroud)

我不确定在数组中放置属性是否是允许基于属性值搜索资产的最佳方式.将属性作为属性直接附加到资产会更好吗?我现在在弹性搜索中进行实验.如果我尝试按原样存储文档,elasticsearch将返回错误:

"error":"MapperParsingException [无法解析[attributes.data]];嵌套:ElasticSearchIllegalArgumentException [unknown property [text]];"

我使用以下映射:

"mappings" : {
    "asset" : {
      "properties" : {
        "_id": {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "_rev": {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "type": {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "attributes": {
          "properties" : {
            "id" : {
              "type" : "string"
            },
            "type" : {
              "type" : "string",
              "index" : "not_analyzed"
            },
            "heading" : {
              "type" : "string"
            },
            "data" : {
              "type" : "string"
            }
          }
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

不知道我在哪里错了.谢谢你的帮助!

特洛伊

Zac*_*ach 26

问题源于文档的结构方式. attribute.data既是字符串的字符串/数组,也是完整的内部对象.ES不允许更改属性的"类型".

基本上,你不能有这个:

"data": [
  "0d7e6233e5f48b4f55c5376bf00b1be5",
  "0d7e6233e5f48b4f55c5376bf00d94cf"
],
Run Code Online (Sandbox Code Playgroud)

还有这个:


"data":[
  {
    "text":"Button 1",
    "checked":false
  },
  {
    "text":"Button 2",
    "checked":true
  }
],

在同一份文件中.data告诉ES 的第一个例子是"数据是一个字符串数组".但接着是第二个例子data说"嘿,我是一个对象!",这就是ES抛出错误的原因.

您可以通过明确声明data为对象并设置enabled:false来回避此问题,但这可能不是您想要的解决方案(因为它只是告诉ES存储data为文本字段,不进行解析.

另一种选择是重组数据,或拆分data成文档(例如父/子映射)