【问题标题】:Nested documents in ElasticsearchElasticsearch 中的嵌套文档
【发布时间】:2013-03-23 20:38:48
【问题描述】:

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

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

不知道我在哪里出错了。感谢您的帮助!

特洛伊

【问题讨论】:

    标签: elasticsearch


    【解决方案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 拆分为它的文档(例如父/子映射)

    【讨论】:

    • 如果我使用父/子映射将其拆分为自己的文档,那么数据可以是不同的类型吗?在数据库中,它可以是字符串、对象数组或字符串数​​组。根据数据类型使用不同的属性会更好吗?一个字符串可能只是一个“文本”属性,一个对象数组可能是一个“选择”属性,等等。
    • 我可能说错了...我不确定父/子类型是否允许在同一字段上混合数据类型。如果可以,将数据拆分为单独的字段将是最简单的方法。由于您必须处理更多属性,因此会增加一点复杂性。
    • 这是有道理的。我将采用这种方法。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    相关资源
    最近更新 更多