23

我正在编写一个资产管理应用程序。它允许用户通过向资产添加 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
       }
   ]
}

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

“错误”:“MapperParsingException [无法解析 [attributes.data]];嵌套:ElasticSearchIllegalArgumentException [未知属性 [文本]];”

我正在使用以下映射:

"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"
            }
          }
        }
      }
    }
  }

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

特洛伊

4

1 回答 1

26

问题出在文档的结构方式上。 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为它的文档(例如父/子映射)

于 2013-03-23T12:38:48.750 回答