是否有办法(查询)在ElasticSearch中加入下面的2个json
{
product_id: "1111",
price: "23.56",
stock: "100"
}
{
product_id: "1111",
category: "iPhone case",
manufacturer: "Belkin"
}
以上2个json在Logstash中以2种不同的类型处理(输入),因此它们的索引在Elasticsearch中不同的'type'字段中可用。
我想要的是在product_id字段上加入2个json。
这取决于您在说JOIN时的意图。Elasticsearch不像普通数据库那样支持表间JOIN。它是一个文本搜索引擎,管理索引内的文档。
另一方面,您可以使用对每种类型都通用的字段在多个类型的同一索引中进行搜索。
例如,我可以用2种类型和它们的数据创建一个索引,如下所示:
curl -XPOST localhost:9200/product -d '{
"settings" : {
"number_of_shards" : 5
}
}'
curl -XPOST localhost:9200/product/type1/_mapping -d '{
"type1" : {
"properties" : {
"product_id" : { "type" : "string" },
"price" : { "type" : "integer" },
"stock" : { "type" : "integer" }
}
}
}'
curl -XPOST localhost:9200/product/type2/_mapping -d '{
"type2" : {
"properties" : {
"product_id" : { "type" : "string" },
"category" : { "type" : "string" },
"manufacturer" : { "type" : "string" }
}
}
}'
curl -XPOST localhost:9200/product/type1/1 -d '{
product_id: "1111",
price: "23",
stock: "100"
}'
curl -XPOST localhost:9200/product/type2/1 -d '{
product_id: "1111",
category: "iPhone case",
manufacturer: "Belkin"
}'
我有效地创建了一个名为product的索引,它有2种类型type1和type2。现在我可以执行以下查询,它将返回两个文档:
curl -XGET 'http://localhost:9200/product/_search?pretty=1' -d '{
"query": {
"query_string" : {
"query" : "product_id:1111"
}
}
}'
{
"took" : 95,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.5945348,
"hits" : [ {
"_index" : "product",
"_type" : "type1",
"_id" : "1",
"_score" : 0.5945348, "_source" : {
product_id: "1111",
price: "23",
stock: "100"
}
}, {
"_index" : "product",
"_type" : "type2",
"_id" : "1",
"_score" : 0.5945348, "_source" : {
product_id: "1111",
category: "iPhone case",
manufacturer: "Belkin"
}
} ]
}
}
原因是因为Elasticsearch将搜索该索引中的所有文档,而不管它们的类型如何。这仍然不同于JOIN,因为Elasticsearch不会对属于每种类型的文档进行笛卡尔积。
希望有帮助
isaac。hazan的回答很好,但我想补充几点,以帮助我解决这种情况:
当我试图解决一个类似的问题时,我来到了这个页面,因为我必须根据另一个索引的文档排除一个索引的多个记录。缺乏关系是非结构化数据库的主要缺点之一。
关于处理关系的elasticsearch文档页面解释了很多。
Elasticsearch中管理关系数据的四种常用技术:
- 应用程序端加入
反规范化数据- <
- 嵌套对象/gh><
- 父/子关系/gh>
最终的解决方案往往需要几种技术的混合。
我主要使用嵌套对象和应用程序端连接。虽然使用相同的字段名可以暂时解决问题,但我认为最好重新考虑并为您的应用程序创建最适合的映射。
例如,您可能发现您想要列出所有价格大于x的产品,或者列出所有不再有库存的产品。要处理这种情况,如果您正在使用上面提到的解决方案之一,则会有所帮助。
要在Elasticsearch上执行连接,请查看Siren "Federate"插件。它通过扩展Elasticsearch本地查询语法来增加连接功能。
https://siren.io/federate/