ElasticSearch Query DSL(五)

ElasticSearch Query DSL(五)

连接查询

在像ElasticSearch这样的分布式搜索引擎上执行完整的SQL连接查询是非常昂贵的。相反ElasticSearch提供了两种形式的连接查询,这样的查询被设计用来水平扩展的。

  • 嵌套查询:文档可能包含nested类型的字段。这些字段被用来索引对象数组,其中每个对象都可以作为独立的文档进行查询。
  • has childhas parentjoin field relationship字段连接关系可以存在一个单独索引内的文档之间。has child查询返回子文档与指定查询匹配的父文档,而has_parent查询返回父文档与指定查询匹配的子文档

提示:设置search.allow_expensive_queriesfalse,关闭连接查询

嵌套查询

包装另一个查询用来搜索嵌套字段

nested查询搜索嵌套字段,就好像搜索一个独立的索引文档一样。如果对象与搜索匹配,则嵌套查询会返回root parent的文档。

查询例子

使用嵌套查询之前,你必须包含一个nested映射。例如:

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "obj1": {
        "type": "nested"
      }
    }
  }
}
'

以下嵌套查询例子:

curl -X GET "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "nested": {
      "path": "obj1",
      "query": {
        "bool": {
          "must": [
            { "match": { "obj1.name": "blue" } },
            { "range": { "obj1.count": { "gt": 5 } } }
          ]
        }
      },
      "score_mode": "avg"
    }
  }
}
'
<nested>顶级参数
  • path:(必须,字符串),你希望查询的嵌套对象的路径

  • query:(必须,查询对象),你希望在<path>路径中的嵌套对象上运行的查询。如果嵌套对象匹配到搜索,nested查询会返回root parent文档。

    您可以使用包含完整路径的点表示法搜索嵌套字段,例如 obj1.name

    自动支持多级嵌套,并检测多级嵌套,从而导致内部嵌套查询自动匹配相关嵌套级别

    有关示例,请参阅Multi-level nested queries

  • score_mode:(可选,字符串),指定匹配到的子对象的相关性分数如果影响root parent文档的相关性分数。有效值为:

    • avg:(默认)
    • max
    • min
    • none
    • sum
  • ignored_umapped:(可选,布尔),是否忽略未映射的<path>并且不返回任何文档而不是错误。默认为false

    如果为 false,并且<path>是未映射的字段,则 Elasticsearch 将返回错误。

    您可以使用此参数查询可能不包含字段<path>的多个索引。

多级嵌套查询

要了解多级嵌套查询的工作原理,首先你需要具有一个嵌套字段的索引。以下请求为包含makemodel嵌套字段的driver索引定义映射。

curl -X PUT "localhost:9200/drivers?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "driver": {
        "type": "nested",
        "properties": {
          "last_name": {
            "type": "text"
          },
          "vehicle": {
            "type": "nested",
            "properties": {
              "make": {
                "type": "text"
              },
              "model": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}
'

然后,在索引中添加一些文档:

curl -X PUT "localhost:9200/drivers/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "driver" : {
        "last_name" : "McQueen",
        "vehicle" : [
            {
                "make" : "Powell Motors",
                "model" : "Canyonero"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}
'
curl -X PUT "localhost:9200/drivers/_doc/2?refresh&pretty" -H 'Content-Type: application/json' -d'
{
  "driver" : {
        "last_name" : "Hudson",
        "vehicle" : [
            {
                "make" : "Mifune",
                "model" : "Mach Five"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}
'

现在可以使用makemodel嵌套字段来进行多级嵌套查询了:

curl -X GET "localhost:9200/drivers/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "nested": {
      "path": "driver",
      "query": {
        "nested": {
          "path": "driver.vehicle",
          "query": {
            "bool": {
              "must": [
                { "match": { "driver.vehicle.make": "Powell Motors" } },
                { "match": { "driver.vehicle.model": "Canyonero" } }
              ]
            }
          }
        }
      }
    }
  }
}
'

查询响应结果为:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.7349272,
    "hits" : [
      {
        "_index" : "drivers",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.7349272,
        "_source" : {
          "driver" : {
            "last_name" : "McQueen",
            "vehicle" : [
              {
                "make" : "Powell Motors",
                "model" : "Canyonero"
              },
              {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
              }
            ]
          }
        }
      }
    ]
  }
}

has child查询

返回与提供查询相匹配的子文档的父文档。你可以使用join字段映射在相同索引内的文档之间创建父子关系。

提示:由于执行了join查询,所以has child相比其他查询性能要低。

查询例子

为了使用has child查询,你的索引映射必须包含join字段。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "parent": "child"
        }
      }
    }
  }
}
'

开始查询:

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "match_all": {}
      },
      "max_children": 10,
      "min_children": 2,
      "score_mode": "min"
    }
  }
}
'
排序

你不能使用标准的排序选项对has child查询结果进行排序。

如果您需要按子文档中的字段对返回的文档进行排序,请使用 function_score 查询并按 _score 排序。例如,以下查询按其子文档的 click_count 字段对返回的文档进行排序。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "function_score": {
          "script_score": {
            "script": "_score * doc[\u0027click_count\u0027].value"
          }
        }
      },
      "score_mode": "max"
    }
  }
}
'

has parent查询

返回与提供查询相匹配的父文档的子文档。你可以使用join字段映射在相同索引内的文档之间创建父子关系。

查询例子

为了使用has parent查询,你的索引映射必须包含join字段。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "parent": "child"
        }
      },
      "tag": {
        "type": "keyword"
      }
    }
  }
}
'

开始查询:

curl -X GET "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "query": {
        "term": {
          "tag": {
            "value": "Elasticsearch"
          }
        }
      }
    }
  }
}
'
排序

你不能使用标准的排序选项对has parent查询结果进行排序。

如果您需要按子文档中的字段对返回的文档进行排序,请使用 function_score 查询并按 _score 排序。例如,以下查询按其子文档的 click_count 字段对返回的文档进行排序。

curl -X GET "localhost:9200/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "score": true,
      "query": {
        "function_score": {
          "script_score": {
            "script": "_score * doc[\u0027view_count\u0027].value"
          }
        }
      }
    }
  }
}
'

parent ID查询

返回连接到特定父文档的子文档。可以使用连接字段映射在同一个索引中的文档之间创建父子关系。

查询例子

要使用parent_id查询,您的索引必须包含一个连接字段映射。要了解如何为parent_id查询设置索引,请尝试下面的示例。

使用连接字段映射创建索引。

curl -X PUT "localhost:9200/my-index-000001?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "my-parent": "my-child"
        }
      }
    }
  }
}
'

索引 ID 为 1 的父文档。

curl -X PUT "localhost:9200/my-index-000001/_doc/1?refresh&pretty" -H 'Content-Type: application/json' -d'
{
  "text": "This is a parent document.",
  "my-join-field": "my-parent"
}
'

索引父文档的子文档。

curl -X PUT "localhost:9200/my-index-000001/_doc/2?routing=1&refresh&pretty" -H 'Content-Type: application/json' -d'
{
  "text": "This is a child document.",
  "my_join_field": {
    "name": "my-child",
    "parent": "1"
  }
}
'

开始查询

curl -X GET "localhost:9200/my-index-000001/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
      "parent_id": {
          "type": "my-child",
          "id": "1"
      }
  }
}
'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值