Как получить текущее время как unix отметку времени для использования скрипта - PullRequest
1 голос
/ 10 июля 2020

У меня есть три поля:

  • date_start (type: date)
  • date_end (type: date)
  • постоянный (тип: bool)

Я хотел бы вернуть все документы с этими условиями:

date_start <= now AND date_end >= now
OR
date_start <= now AND permanent == true

Как лучше всего это сделать?

Я подумал, что будет использовать скрипт вот так:

{
 "query": {
   "bool": {
     "filter": [
       {
         "script": {
           "script": {
             "source": "((doc['date_start'].value <= params.now) && (doc['date_end'].value >= params.now)) || ((doc['date_start'].value <= params.now) && (doc['permanent'].value == params.permanent))"
           },
           "lang": "painless",
           "params": {
             "now": "1594390526",
             "permanent": true
           }
         }
       }
     ]
   }
 }
}

Но есть проблема со сравнением типов дат, и я не знаю, как ее решить. Спасибо

Ответы [ 2 ]

0 голосов
/ 15 июля 2020

Спасибо, Джо, за твой ответ. Мне не удалось реализовать это правильно, но я думаю, что это хорошая отправная точка для решения сценария.

Однако я нахожу другой способ сделать то, что я хотел, используя комбинацию диапазона и bool / should.

Вот оно:

{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "date_start": {
              "lte": "now"
            }
          }
        },
        {
          "bool": {
            "should": [
              {
                "range": {
                  "date_end": {
                    "gte": "now"
                  }
                }
              },
              {
                "term": {
                  "permanent": true
                }
              }
            ]
          }
        }
      ]
    }
  }
}
0 голосов
/ 10 июля 2020

Dynami c now это целенаправленно отключено безболезненно. Из документации:

Для этого есть две основные причины. Во-первых, сценарии часто запускаются один раз для каждого документа, поэтому каждый раз, когда сценарий запускается, возвращается другой now. Во-вторых, сценарии часто выполняются распределенным образом без возможности надлежащей синхронизации now. Вместо этого передайте определяемый пользователем параметр либо со строковым значением datetime, либо с числовым значением c datetime для now. Число c datetime предпочтительнее, так как нет необходимости анализировать его для сравнения.

Подсказки о том, почему ваш скрипт может не работать:

params.now должно быть целым числом с интервалом в секунду, а не строкой. Кроме того, вам нужно будет получить доступ к значениям меток времени ваших дат, используя .millis, а затем преобразовать их в секунды эпохи.

Примеры:

{
  "query": {
    "bool": {
      "filter": [
        {
          "script": {
            "script": {
              "source": """
                def now = params.now;
                def start = doc['date_start'].value.millis/1000;
                def end = doc['date_end'].value.millis/1000;
                
                def is_permanent = doc['permanent'].value; 
                
                return (
                  (start <= now) && (end >= now)) ||
                  ((start <= now) && (is_permanent == params.permanent)
                )
              """,
              "lang": "painless",
              "params": {
                "now": 1594399256,
                "permanent": true
              }
            }
          }
        }
      ]
    }
  }
}

Математика даты и времени хорошо описана здесь .

...