在ElasticSearch中加入查询

时间:2014-03-24 13:38:20

标签: elasticsearch logstash kibana

有没有办法(查询)在ElasticSearch

中加入以下2个JSON
{
product_id: "1111",
price: "23.56",
stock: "100"
}

{
product_id: "1111",
category: "iPhone case",
manufacturer: "Belkin"
}

在Logstash中,在2种不同类型下处理(输入)2个以上的JSON,因此它们的索引可以使用不同的'类型'在Elasticsearch提交。

我想要的是在product_id字段上加入2个JSON。

3 个答案:

答案 0 :(得分:15)

这取决于您说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的索引,类型为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不会对属于每种类型的文档执行笛卡尔积。

希望有所帮助

答案 1 :(得分:2)

isaac.hazan的回答非常有效,但我想补充几点帮助我解决这种情况:

当我试图解决类似的问题时,我登陆了这个页面,因为我必须根据另一个索引的文档排除一个索引的多个记录。缺乏关系是非结构化数据库的主要缺点之一。

Handling Relationships上的elasticsearch文档页面解释了很多。

  

在Elasticsearch中使用四种常用技术来管理关系数据:

     
      
  • 应用程序端连接
  •   
  • 数据非规范化
  •   
  • 嵌套对象
  •   
  • 家长/子女关系
  •   
     

最终解决方案通常需要混合使用其中一些技术。

我主要使用嵌套对象和应用程序端连接。虽然使用相同的字段名称可以暂时解决问题,但我认为最好重新考虑并为您的应用程序创建最适合的映射。

例如,您可能会发现要列出价格大于x的所有产品,或者列出所有没有库存的产品。要处理这种情况,如果您使用上述解决方案之一,它会有所帮助。

答案 2 :(得分:0)

要在Elasticsearch上执行联接,请看一下Siren的“ Federate”插件。它通过扩展Elasticsearch本机查询语法来添加联接功能。

https://siren.io/federate/