我正在尝试索引具有属性值对的弹性搜索文档。示例文件:
{
id: 1,
name: "metamorphosis",
author: "franz kafka"
}
{
id: 2,
name: "techcorp laptop model x",
type: "computer",
memorygb: 4
}
{
id: 3,
name: "ss2014 formal shoe x",
color: "black",
size: 42,
price: 124.99
}
然后,我需要查询:
1. "author" EQUALS "franz kafka"
2. "type" EQUALS "computer" AND "memorygb" GREATER THAN 4
3. "color" EQUALS "black" OR ("size" EQUALS 42 AND price LESS THAN 200.00)
存储这些文档以便有效查询它们的最佳方法是什么?我应该完全按照示例中的说明存储它们吗?或者我应该将它们存储起来:
{
fields: [
{ "type": "computer" },
{ "memorygb": 4 }
]
}
或者喜欢:
{
fields: [
{ "key": "type", "value": "computer" },
{ "key": "memorygb", "value": 4 }
]
}
我应该如何映射我的索引以便能够执行我的相等和范围查询?
答案 0 :(得分:4)
如果有人还在寻找答案,我写了一篇关于如何将任意数据索引到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
查询。
答案 1 :(得分:1)
Elastic Search是一种无模式数据存储,它允许对新属性进行动态索引,并且对可选字段没有性能影响。您首先映射是绝对正常的,您可以围绕您的动态属性进行布尔查询。 通过使它们成为嵌套字段没有固有的性能优势,它们无论如何都会在像index.type,fields.memorygb等索引上被夷为平地。
相反,您尝试存储为键值对的最后一个映射会对性能产生影响,因为您必须查询2个不同的索引字段,即key ='memorygb'和value = 4
查看有关动态映射的文档:
Elasticsearch最重要的功能之一是它能够无模式。如果对象是,则没有性能开销 动态,能力 关闭它作为安全机制提供所以“畸形” 错误地,对象不会是我们不希望的索引数据 索引。
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-object-type.html
答案 2 :(得分:0)
您需要从here看过滤查询:
您必须与匹配查询一起使用范围查询