javascriptnode.jselasticsearchelasticsearch-queryelasticsearch-date

Elasticsearch string matching multiple fields in query


I'm trying to query my Elastic Search database and match several fields, however, I get:

[match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]

Which is strange because surely I must be able to use match and then my field name to match some text right?

The fields I'm trying to query are inside my data object, which is custom, and since adding a (dot) doesn't work in here, I'm wrapping that, my data:

{
    "_index": "my_table",
    "_type": "_doc",
    "_id": "IVnGuXcBt3ZsPNCw23Eg",
    "_version": 1,
    "_seq_no": 0,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "mappings": {
            "properties": {
                "period_from": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "fielddata": true
                },
                "period_to": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "fielddata": true
                },
                "created_at": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "fielddata": true
                },
                "updated_at": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss",
                    "fielddata": true
                }
            }
        },
        "data": {
            "dataset": "events",
            "event_category": "test1",
            "event_action": "test2",
            "event_count": "199",
            "period_from": "2021-02-19 00:02:00",
            "period_to": "2021-02-19 10:02:29",
            "created_at": "2021-02-19 10:02:79",
            "updated_at": "2021-02-19 10:02:79"
        },
        "period_from": "2021-02-19 00:02:00",
        "period_to": "2021-02-19 10:02:29",
        "created_at": "2021-02-19 10:02:18",
        "updated_at": "2021-02-19 10:02:18"
    }
}

What am I missing here:

events = await elastic.find('my_table', {
  query: {
    match: {
      'data.event_category': 'test1'
    },
    match: {
      'data.event_action': 'test2'
    },
    range: {
      period_from: {
        gte: moment(from).format('YYYY-MM-DD HH:MM:SS')
      },
      period_to: {
        lte: moment(to).format('YYYY-MM-DD HH:MM:SS')
      }
    }
  }
})

Solution

  • Once you've correctly set up the date fields' mappings, use this:

    {
      query: {
        bool: {
          must: [
            {
              match: {
                "data.event_action": "test2"
              }
            },
            {
              range: {
                period_from: {
                  gte:  moment(from).format('YYYY-MM-DD HH:MM:SS')
                }
              }
            },
            {
              range: {
                period_to: {
                  lte: moment(to).format('YYYY-MM-DD HH:MM:SS')
                }
              }
            }
          ]
        }
      }
    }