在Elasticsearch中搜索对象数组

时间:2019-07-09 11:22:56

标签: elasticsearch

我将调查回复存储在我的ES中,所以发生的事情是人们使用移动应用填写调查表格,这些表格回复被发送到后端,然后像这样存储在ES中,这就是问题的答案的形式是商店

answers {
  "uKeCywV4SAgD8YGReSkn" : {
              "_id" : "b465de5e-5468-40fe-8a8d-fc02083",
              "responseVersionNumber" : 1,
              "options" : [
                {
                  "id" : "32700fb5-51d2-4617-b65f-831b83c88080"
                },
                {
                  "id" : "32700fb5-51d2-4617-b65f-831b83c87777"
                }
}

answers文档在其问题ID下包含每个问题的答案。您在下面看到的字符串是问题ID,以同样的方式,所有其他答案在该响应的文档中分别以相应的问题ID存储在ES中。

现在,我想搜索这些答案,上面的答案是mcq多选类型,因为您可以看到文本字段(包含)答案值(例如,用户Gardening and Sports的爱好)和options id array都可以用于此目的,我可以将我的Web应用程序中的option id数组发送到ES或文本值(或称为标签的选项标签),也可以使用问题ID,例如,假设我有一个ID为q1的问题,所以我想让我的查询说给我看问题q1都回答a1和a2的文档

我一直想探索options id的方法,这是我为其构建的一个示例查询。

 {
    "_source": {"includes": ["answers.uKeCywV4SAgD8YGReSkn.text", "answers.uKeCywV4SAgD8YGReSkn.questionTypeCode"]},
    "query": {
        "bool": {
            "filter": [{
                "bool": {
                    "must": [{
                        "match": {
                            "answers.uKeCywV4SAgD8YGReSkn.options.id": "32700fb5-51d2-4617-b65f-831b83c88080"
                        }
                    },
                        {
                        "match": {
                            "answers.uKeCywV4SAgD8YGReSkn.options.id": "32700fb5-51d2-4617-b65f-831b83c87777"
                        }
                    }
                    ]
                }
            }, {
                "match": {
                    "formId": "hHhcLKh9st1vFr8nDY4a"
                }
            }, {
                "range": {
                    "_updated_at": {
                        "from": "1970-01-01T00:00:00.000+0000",
                        "include_lower": true,
                        "include_upper": true,
                        "to": null
                    }
                }
            }]
        }
    }
 }

我想知道采用这种方法是否有缺点,而不是同时使用两个选项标签来搜索text字段

根据映射,这是两个字段的设置方式

"questionId": {
   "type": "keyword",
   "index": false
},

"text": {
    "type": "text"
},

"options": {
    "enabled": false
},

1 个答案:

答案 0 :(得分:1)

您的问题有点难以理解...但是对于我来说这可能太早了:)我不太了解“选项ID”字段在这里应该做什么。您的答案是否用于多个问题?还是您的答案有多种选择?如果是这样,用户为什么还可以回复文本?另外,为什么要将所有字段分为两个层次?为什么不将它们平放呢?将字段命名为问题ID似乎很麻烦。

尽管我不太确定您在这里要问什么,但我可以建议一些可能会有所帮助的事情。

我最近一直在使用Elasticsearch,尤其是嵌套对象数组。您可能正在寻找的是嵌套数据类型。我强烈建议您阅读documentation

简而言之,它将允许您将“选项ID”存储为可使用自己的nested query查询的嵌套对象。这是完成对嵌套对象搜索的最简单方法。

首先,您需要指定映射以告诉Elasticsearch“ options”是嵌套的数据类型:

PUT INDEX_NAME
{
  "mappings": {
    "DOCUMENT_TYPE": {
      "properties": {
        "options": {"type": "nested"}
      }
    }
  }
}

然后,在为文档建立索引之后,可以使用嵌套查询来查询该字段。例如,如果您想要选项ID“ ID_123”的所有答案:

GET INDEX_NAME/_search
{
  "query": {
    "nested": {
      "path": "options",
      "query": {
        "match": {
          "options.id.keyword": "ID_123"
        }
      }
    }
  }
}

您还可以“嵌套”嵌套查询,以添加更多参数,例如是否要获得每个选项ID的答案,该参数在过去一天也已更新。

我希望这会有所帮助。如果不是,请尝试更清楚地描述您要做什么:)