Home > Net >  Elasticsearch - Query string w/ time range
Elasticsearch - Query string w/ time range

Time:10-14

essentially I want to find documents where "variable ABC contains 'apple' and only count documents from 1 day ago". For context, this is the request body of a curl request.

This will return all documents where ABC is 'apple':

 '{ 
    "query": {
        "query_string": {
            "query": "apple",
             "default_field": "ABC"
            }
        }
    }'

This unfortunately does not work:

'{ 
    "query": {
        "query_string": {
            "query": "apple",
             "default_field": "ABC"
            }
        },
        "filter": {
            "range": {"nest.nest1.nest2.timestamps.start": {"gte": "now-1d"}}
            }
        }
    }'

Sample document I want to find, highly abbreviated, and thanks for helping:

    {
    "hits": [
      {
        "_index": "indexabc",
        "_id": "IDabc",
        "_score": "15"
        "_source": {
             "ABC": "applebottom",
             "nest": {
                 "nest1": {
                    "nest2": {
                        "timestamps": {
                            "start": "2022-09-01T08:00:10 00:00",
                            "send": "2022-09-01T08:16:20 00:00"
                        }
                    }
                 }
              }
           }
        }
     ]

        

CodePudding user response:

You need to do it this way:

{
  "query": {
   "bool": {
    "must": [
      {
        "query_string": {
          "query": "apple",
          "default_field": "ABC"
        }
      }
    ],
    "filter": [
      {
        "range": {
          "nest.nest1.nest2.timestamps.start": {
            "gte": "now-1d"
          }
        }
      }
    ]
   }
  }
}

CodePudding user response:

There are multiple ways to solve this

1. Wildcard

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "*apple*", --> wildcard
            "default_field": "ABC"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "nest.nest1.nest2.timestamps.start": {
              "gte": "now-1y"
            }
          }
        }
      ]
    }
  }
}

wildcards are slow. If you are facing performance issues, then there are other ways to resolve this.

2. Prefix

if your search text is at start of word, you can use a simple prefix query

{
  "query": {
    "bool": {
      "must": [
        {
          "prefix": {
            "ABC": "apple"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "nest.nest1.nest2.timestamps.start": {
              "gte": "now-1y"
            }
          }
        }
      ]
    }
  }
}

3. NGrams

PUT index24
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 5,
          "max_gram": 5
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "ABC": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
} 


GET index24/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "default_field": "ABC",
            "query": "apple"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "nest.nest1.nest2.timestamps.start": {
              "gte": "now-1y"
            }
          }
        }
      ]
    }
  }
}

for "applebottom" following tokens will be generated ["apple","ppleb","plebo","lebot","ebott","bottom"]. You can adjust tokens generated using "min_gram": 5 and "max_gram": 5.

Ngrams will let you search anywhere between a text and give better search performance as tokens are created at index time. It will give better search performance at expense of increase in index size

  • Related