2015-11-05 1 views
9

Attualmente so già come filtrare un intervallo di giorni da un campo di data (data/ora). Questo è un compito facile:ElasticSearch: come eseguire una query su un campo data utilizzando un filtro di intervallo di ore

"range": { 
    "date": { 
     "gte": "2015-11-01", 
     "lte": "2015-11-30" 
    } 
} 

Ma come filtrare date in cui siete interessati a intervalli in base a ore come gte: "8:00:00" e LTE: "10:00:00"? È possibile?

Il mio fabbisogno in altre parole: Come ottenere tutti gli eventi in corso questo mese (15-11-01/15-11-30) ma solo tra le 8:00:00 e le 10:00:00?

+0

Tra quelle ore, per qualsiasi giorno? –

+0

Diciamo che voglio ottenere tutti i record tra 2015-10-01 e 2015-12-31, ma solo quelli che sono avvenuti tra questa fascia oraria: "8:00:00" e "10:00:00" – xtingray

+0

Possibile duplicato di [Elasticsearch: filtraggio per data e ora come campi diversi] (http://stackoverflow.com/questions/33508044/elasticsearch-filtering-by-date-and-time-as-different-fields) – Val

risposta

3

se ho capito bene la tua domanda, allora penso che si deve aggiungere nuovo campo che indicizza solo il tempo come

PUT your_index 
{ 
    "mappings": { 
    "your_type": { 
     "properties": { 
     "time": { 
      "type": "date", 
      "format": "HH:mm:ss" 
     } 
     } 
    } 
    } 
} 

Poi si può interrogare come questo

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "range": { 
      "date": { 
       "gte": "2015-11-01", 
       "lte": "2015-11-30" 
      } 
      } 
     }, 
     { 
      "range": { 
      "time": { 
       "gte": "08:00:00", 
       "lte": "10:00:00" 
      } 
      } 
     } 
     ] 
    } 
    } 
} 

Fa questo aiuto?

+0

In questo momento, il mio campo "data" ha questo tipo: {"tipo": "data", "formato": "dateOptionalTime"}, supporta record come questo 2015-11-04T22: 10: 02 e sfortunatamente posso t modificare i miei indici – xtingray

+0

anche nella mia applicazione, ho lo stesso formato ma è possibile cercare solo come '" gte ":" 2015-10-02T13: 34: 09 "," lte ":" 2015-10-05T12 : 00: 00 "' che ti darà risultati tra quella gamma e non quello che vuoi che è l'intervallo di tempo specifico in giorni specifici – ChintanShah25

15

È possibile farlo con il vostro filtro range per filtrare i giorni corretti e poi con un filtro script per filtrare le ore desiderate, in questo modo:

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "range": { 
       "date": { 
        "gte": "2015-11-01", 
        "lte": "2015-11-30" 
       } 
       } 
      }, 
      { 
       "script": { 
       "script": "doc.date.date.getHourOfDay() >= min && doc.date.date.getHourOfDay() <= max", 
       "params": { 
        "min": 8, 
        "max": 10 
       } 
       } 
      } 
      ] 
     } 
     } 
    } 
    } 
} 

Nota che è necessario fare in modo di enable dynamic scripting in ordine perché questa query funzioni.

+0

Grazie. Funziona perfettamente. A proposito, ho provato ad aggiungere un altro script per filtrare i minuti usando il metodo "getMinuteOfHour" ma non ha funzionato. Qualche suggerimento? – xtingray

+0

Puoi mostrare quello script? – Val

+0

Ciao @Val potresti dirmi da dove viene il metodo 'getHourOfDay()'? il motore di script groovy usa 'joda' per la manipolazione datetime? Non sono riuscito a trovare alcuna documentazione – ChintanShah25

0

Ecco quello che ho, una volta usato per ottenere solo i risultati di inizio del giorno corrente a 06:00:

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "query_string": { 
      "query": "(log_message:\"My Search String\")" 
      } 
     }, 
     { 
      "range": { 
      "@timestamp": { 
       "time_zone": "CET", 
       "gt": "now-24h/d", 
       "lte": "now-24h/d+18h" 
      } 
      } 
     } 
     ] 
    } 
    } 
} 

la parte importante è "ora-24h/d" che rotonda a mezzanotte/inizio del giorno corrente, anche se è un po 'complicato in quanto dipende da se si utilizza gt/lt (e), vedere reference doc per i dettagli.