1

I need to search my index based on a timestamp.

The documents have these field combinations:

  • start_time and end_time

or

  • just start_time (no end_time field)

Pseudo query: . For a given timestamp, I wish to return all documents where an id matches, and also:
timestamp >= start_time && timestamp < end_time

but if there is no end_time field, then the query needs to be this:
(not exists end_time) && (timestamp > start_time)

Elastic query . This is where I am going mad. I can't get an elastic query equivilent to that pseudo query above. Perhaps I am approaching it the wrong way (entirely possible). Here is what I have:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "id_s": "SomeIdValue"
          }
        },
        {
          "bool": {
            "should": [
              {
                "must": [
                  {
                    "must_not": [
                      {
                        "exists": {
                          "field": "end_time_dt"
                        }
                      }
                    ]
                  },
                  {
                    "range": {
                      "start_time_dt": {
                        "lte": "2019-07-12T03:20:22"
                      }
                    }
                  }
                ]
              },
              {
                "filter": [
                  {
                    "range": {
                      "start_time_dt": {
                        "lte": "2019-07-12T03:20:22"
                      }
                    }
                  },
                  {
                    "range": {
                      "end_time_dt": {
                        "gte": "2019-07-12T03:20:22"
                      }
                    }
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  }
}

But this gives me [must] query malformed, no start_object after query name

How do I construct this query? Am I on the right track?

thanks in advance!

3 Answers 3

2

Your query is syntactically wrong. The correct query would be:

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "id_s": "SomeIdValue"
          }
        },
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "must_not": [
                    {
                      "exists": {
                        "field": "end_time_dt"
                      }
                    }
                  ],
                  "must": [
                    {
                      "range": {
                        "start_time_dt": {
                          "lte": "2019-07-12T03:20:22"
                        }
                      }
                    }
                  ]
                }
              },
              {
                "bool": {
                  "must": [
                    {
                      "range": {
                        "start_time_dt": {
                          "lte": "2019-07-12T03:20:22"
                        }
                      }
                    },
                    {
                      "range": {
                        "end_time_dt": {
                          "gte": "2019-07-12T03:20:22"
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

that has fixed the syntax, thank you - however it returns 0 hits. Is my actual logic correct?
@Stretch I updated my query with logic correction. You used lte and gte in opposite way. Also in two case you want only lt and gt
actually your first query was correct, and it works - my bad. My lt/gt logic in the original post is also correct - it does not need to be switched. In this query, I am looking for documents that existed at the time 2019-07-12T03:20:22. Therefore, the start time must be lt this time, and the end time must be gt this time. If you switch it back, I'll mark as the correct answer. Thanks very much for your help!
@Stretch Reverted back the query
0

There is a slight mistake in the logic. Ideally, comparison should be like this gte start_time_dt and lte end_time_dt. You did other way round so that translates to timestamp <= start_time && timestamp > end_time.

The correct query is

{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "id_s": "SomeIdValue"
          }
        },
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "must_not": [
                    {
                      "exists": {
                        "field": "end_time_dt"
                      }
                    }
                  ],
                  "must": [
                    {
                      "range": {
                        "start_time_dt": {
                          "gte": "2019-07-12T03:20:22"
                        }
                      }
                    }
                  ]
                }
              },
              {
                "bool": {
                  "must": [
                    {
                      "range": {
                        "start_time_dt": {
                          "gte": "2019-07-12T03:20:22"
                        }
                      }
                    },
                    {
                      "range": {
                        "end_time_dt": {
                          "lte": "2019-07-12T03:20:22"
                        }
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Hope this helps!!

3 Comments

I think I was correct actually. I want to see if a given timestamp falls within start and end, so start<-----TS------>end - so, ts gte start && ts lte end
Yes, but in the query you have ` { "range": { "start_time_dt": { "lte": "2019-07-12T03:20:22" } } }, { "range": { "end_time_dt": { "gte": "2019-07-12T03:20:22" } } }`
which is correct. I need the start time to be earlier than the timestamp ("2019-07-12T03:20:22) and the end time must come after 2019-07-12T03:20:22, hence gte (or maybe just gt will do)
0

I believe this block should be must not should as mentioned in the answer. The reason I say is both those conditions: must ( not exists AND range ) is what the OP intention I believe

{
          "bool": {
            "must": [     <====== mentioned it as should
              {
                "bool": {
                  "must_not": [
                    {
                      "exists": {
                        "field": "end_time_dt"
                      }
                    }
                  ],
                  "must": [
                    {
                      "range": {
                        "start_time_dt": {
                          "lte": "2019-07-12T03:20:22"
                        }
                      }
                    }
                  ]
                }
              },

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.