如果有人还在寻找答案,我写了一篇关于如何将任意数据索引到 Elasticsearch 中然后按特定字段和值进行搜索的帖子。所有这一切,都不会破坏您的索引映射。
帖子:http ://smnh.me/indexing-and-searching-arbitrary-json-data-using-elasticsearch/
简而言之,您将需要创建帖子中描述的特殊索引。然后你需要使用flattenData
函数https://gist.github.com/smnh/30f96028511e1440b7b02ea559858af4来展平你的数据。然后,扁平化的数据可以安全地索引到 Elasticsearch 索引中。
例如:
flattenData({
id: 1,
name: "metamorphosis",
author: "franz kafka"
});
将产生:
[
{
"key": "id",
"type": "long",
"key_type": "id.long",
"value_long": 1
},
{
"key": "name",
"type": "string",
"key_type": "name.string",
"value_string": "metamorphosis"
},
{
"key": "author",
"type": "string",
"key_type": "author.string",
"value_string": "franz kafka"
}
]
和
flattenData({
id: 2,
name: "techcorp laptop model x",
type: "computer",
memorygb: 4
});
将产生:
[
{
"key": "id",
"type": "long",
"key_type": "id.long",
"value_long": 2
},
{
"key": "name",
"type": "string",
"key_type": "name.string",
"value_string": "techcorp laptop model x"
},
{
"key": "type",
"type": "string",
"key_type": "type.string",
"value_string": "computer"
},
{
"key": "memorygb",
"type": "long",
"key_type": "memorygb.long",
"value_long": 4
}
]
然后,您可以使用构建 Elasticsearch 查询来查询您的数据。每个查询都应该指定键和值的类型。如果您不确定索引具有哪些键或类型,您可以运行聚合来查找,这也在帖子中进行了讨论。
例如,要查找author == "franz kafka"
需要执行以下查询的文档:
{
"query": {
"nested": {
"path": "flatData",
"query": {
"bool": {
"must": [
{"term": {"flatData.key": "author"}},
{"match": {"flatData.value_string": "franz kafka"}}
]
}
}
}
}
}
要查找type == "computer" and memorygb > 4
需要执行以下查询的文档:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "flatData",
"query": {
"bool": {
"must": [
{"term": {"flatData.key": "type"}},
{"match": {"flatData.value_string": "computer"}}
]
}
}
}
},
{
"nested": {
"path": "flatData",
"query": {
"bool": {
"must": [
{"term": {"flatData.key": "memorygb"}},
{"range": {"flatData.value_long": {"gt": 4}}}
]
}
}
}
}
]
}
}
}
在这里,因为我们希望同一个文档同时匹配两个条件,所以我们使用bool
带有包含must
两个查询的子句的外部nested
查询。