ElasticSearch - найти все документы, вложенные документы которых не пересекаются с диапазоном дат - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть индекс с именем employees с вложенной коллекцией диапазонов дат и времени, называемый shifts.Мне нужно найти всех пользователей, которые доступны между определенным входным диапазоном даты и времени (то есть входной диапазон дат не пересекается ни с какими сдвигами)Как я могу сделать это с ElasticSearch?Вот как выглядит мой индекс (сокращен для краткости), не уверен, что это правильно:

{
    "mappings": {
        "employee": {
            "properties": {
                "email": {
                    "type": "text",
                    "fields": {
                        "raw": {
                            "type": "keyword"
                        }
                    }
                },
                "shifts": {
                    "type": "nested",
                    "properties": {
                        "shift": {
                            "type": "date_range"
                        }
                    }
                }
            }
        }
    }
}

1 Ответ

0 голосов
/ 15 февраля 2019

Всякий раз, когда у вас есть вложенный тип данных, как вы упомянули, вам нужно будет использовать вложенный запрос

Обратите внимание, что я использовал простой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: Теперь, если вы хотите узнать список пользователей, которые доступныв этот точный конкретный промежуток времени , тогда запрос диапазона разрешит поле с именем relation, где вы можете указать contains, что даст вам только возможных кандидатов, доступных в этом конкретном временном диапазоне.

Запросы диапазона по полям диапазона поддерживают параметр отношения, который может быть одним из WITHIN, CONTAINS, INTERSECTS (по умолчанию).

POST someindex/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "shifts",
            "query": {
              "range": {
                "shifts.shift": {
                  "gte": "2019-01-01",
                  "lte": "2019-01-03",
                  "relation": "contains"
                }
              }
            }
          }
        }
      ]
    }
  }
}

Дайте мне знать, если это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...