我写了一篇关于如何将任意数据索引到 Elasticsearch 中然后按特定字段和值进行搜索的帖子。所有这一切,都不会破坏您的索引映射。
帖子在这里:http://smnh.me/indexing-and-searching-arbitrary-json-data-using-elasticsearch/
简而言之,您需要执行以下步骤才能获得所需的内容:
- 创建帖子中描述的特殊索引。
- 使用
flattenData 函数展平要索引的数据:
https://gist.github.com/smnh/30f96028511e1440b7b02ea559858af4。
-
使用原始数据和展平数据创建一个文档并将其索引到 Elasticsearch:
{
"data": { ... },
"flatData": [ ... ]
}
可选:使用 Elasticsearch 聚合来查找已索引的字段和类型。
- 对
flatData 对象执行查询以找到您需要的内容。
示例
根据您最初的问题,假设第一位活动主持人创建了一个包含以下字段的表单来注册科学活动的成员:
-
name 字符串
-
age 长
-
sex long - 0 男性,1 女性
除了这些数据,相关事件可能还有某种id,我们称之为eventId。所以最终的文档可能如下所示:
{
"eventId": "2T73ZT1R463DJNWE36IA8FEN",
"name": "Bob",
"age": 22,
"sex": 0
}
现在,在我们索引此文档之前,我们将使用 flattenData 函数将其展平:
flattenData(document);
这将产生以下数组:
[
{
"key": "eventId",
"type": "string",
"key_type": "eventId.string",
"value_string": "2T73ZT1R463DJNWE36IA8FEN"
},
{
"key": "name",
"type": "string",
"key_type": "name.string",
"value_string": "Bob"
},
{
"key": "age",
"type": "long",
"key_type": "age.long",
"value_long": 22
},
{
"key": "sex",
"type": "long",
"key_type": "sex.long",
"value_long": 0
}
]
然后我们将这些数据包装在一个文档中,就像我之前展示的那样,并对其进行索引。
然后,第二个活动主持人创建另一个表单,该表单具有一个新字段,具有相同名称和类型的字段,以及一个具有相同名称但具有不同类型的字段:
-
name 字符串
-
city 字符串
-
sex 字符串 - “男”或“女”
这位活动主持人决定不再使用0 和1 来表示男性和女性,而是允许在两个字符串之间进行选择——“男性”和“女性”。
让我们尝试将这个表单提交的数据展平:
flattenData({
"eventId": "F1BU9GGK5IX3ZWOLGCE3I5ML",
"name": "Alice",
"city": "New York",
"sex": "female"
});
这将产生以下数据:
[
{
"key": "eventId",
"type": "string",
"key_type": "eventId.string",
"value_string": "F1BU9GGK5IX3ZWOLGCE3I5ML"
},
{
"key": "name",
"type": "string",
"key_type": "name.string",
"value_string": "Alice"
},
{
"key": "city",
"type": "string",
"key_type": "city.string",
"value_string": "New York"
},
{
"key": "sex",
"type": "string",
"key_type": "sex.string",
"value_string": "female"
}
]
然后,在将扁平化数据包装到文档中并将其索引到 Elasticsearch 中之后,我们可以执行复杂的查询。
例如,要查找为 ID 2T73ZT1R463DJNWE36IA8FEN 注册的名为“Bob”的成员,我们可以执行以下查询:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "flatData",
"query": {
"bool": {
"must": [
{"term": {"flatData.key": "eventId"}},
{"match": {"flatData.value_string.keyword": "2T73ZT1R463DJNWE36IA8FEN"}}
]
}
}
}
},
{
"nested": {
"path": "flatData",
"query": {
"bool": {
"must": [
{"term": {"flatData.key": "name"}},
{"match": {"flatData.value_string": "bob"}}
]
}
}
}
}
]
}
}
}