小编典典

Elasticsearch中的嵌套文档

elasticsearch

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

{
   "_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
       }
   ]
}

我不确定将属性放入数组是否是允许基于属性值搜索资产的最佳方法。将属性直接附加到资产作为属性会更好吗?我正在用Elasticsearch做实验。如果我尝试按原样存储文档,elasticsearch将返回错误:

“错误”:“ MapperParsingException
[无法解析[attributes.data]];嵌套:ElasticSearchIllegalArgumentException
[未知属性[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"
            }
          }
        }
      }
    }
  }

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

特洛伊


阅读 661

收藏
2020-06-22

共1个答案

小编典典

问题是由文档的结构方式引起的。 attribute.data既是一个字符串/字符串数组,又是一个完整的内部对象。ES不允许更改属性的“类型”。

基本上,您不能拥有以下功能: ``

"data": [
  "0d7e6233e5f48b4f55c5376bf00b1be5",
  "0d7e6233e5f48b4f55c5376bf00d94cf"
],

还有这个:

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

在同一文档中。的第一个实例data告诉ES“数据是一个字符串数组”。但是第二个实例data说“嘿,我是一个对象!”,这就是ES抛出错误的原因。

您可以通过显式声明data为对象并设置 enabled为false 来避开此问题
但这可能不是您想要的解决方案(因为这只是告诉ES将其存储data为文本字段,而无需解析。

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

2020-06-22