我有一个名为employees
的索引,其中包含一个嵌套的日期时间范围集合,称为shifts
。我需要找到在特定输入日期时间范围内可用的所有用户(即输入日期范围不与任何班次相交)。如何使用ElasticSearch做到这一点?这就是我的索引的样子(为简洁起见,对其进行了整理),不确定是否正确:
{
"mappings": {
"employee": {
"properties": {
"email": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"shifts": {
"type": "nested",
"properties": {
"shift": {
"type": "date_range"
}
}
}
}
}
}
}
答案 0 :(得分:2)
只要您拥有nested数据类型,就需要使用nested query
请注意,我在映射中为yyyy-MM-dd
使用了简单的shifts.shift
格式,如下所示。我还提供了示例文档,查询和响应。
请注意我提到的两个方案/查询,以便您清楚最适合您的用例的情况。
PUT someindex
{
"mappings": {
"employee": {
"properties": {
"email": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"shifts": {
"type": "nested",
"properties": {
"shift": {
"type": "date_range",
"format": "yyyy-MM-dd"
}
}
}
}
}
}
}
POST someindex/employee/1
{
"email": "john@abc.com",
"shifts": [
{
"shift": {
"gte": "2019-01-01",
"lte": "2019-01-03"
}
}
]
}
POST someindex/employee/2
{
"email": "jane@abc.com",
"shifts": [
{
"shift": {
"gte": "2019-01-04",
"lte": "2019-01-07"
}
}
]
}
POST someindex/employee/3
{
"email": "jack@abc.com",
"shifts": [
{
"shift": {
"gte": "2019-01-08",
"lte": "2019-01-10"
}
}
]
}
场景1:在特定范围内可用的用户列表,例如从2019-01-01
到2019-01-04
。还要注意在下面的查询中使用nested
关键字
POST someindex/_search
{
"query":{
"bool":{
"must":[
{
"nested":{
"path":"shifts",
"query":{
"range":{
"shifts.shift":{
"gte":"2019-01-01",
"lte":"2019-01-04",
}
}
}
}
}
]
}
}
}
查看示例文档,您可以看到结果返回了John
和Jane
。请注意,您会同时获得这两者,因为默认情况下,范围为intersection
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "someindex",
"_type" : "employee",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"email" : "jane@abc.com",
"shifts" : [
{
"shift" : {
"gte" : "2019-01-04",
"lte" : "2019-01-07"
}
}
]
}
},
{
"_index" : "someindex",
"_type" : "employee",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"email" : "john@abc.com",
"shifts" : [
{
"shift" : {
"gte" : "2019-01-01",
"lte" : "2019-01-03"
}
}
]
}
}
]
}
}
场景2:现在,如果您想了解在该确切时间段可用的用户列表,则范围查询将允许一个名为{{ 1}},您可以提及relation
,这只会为您提供在特定时间范围内可用的候选人。
范围字段上的范围查询支持一个关系参数,该参数可以 成为WITHIN,CONTAINS,INTERSECTS(默认值)之一。
contains
让我知道这是否有帮助!