Elastic Search filter by count of a nested document

后端 未结 1 1666
忘掉有多难
忘掉有多难 2021-01-13 13:10

I have an elastic search index for firms, that has a nested object called transactions. The transactions have at least a date

1条回答
  •  迷失自我
    2021-01-13 13:38

    I don't think you have other option than using a script. Something like this:

    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "transactions",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "transactions.side": "buyer"
                        }
                      },
                      {
                        "range": {
                          "transactions.date": {
                            "from": "2014-10-24",
                            "to": "2015-10-24"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "filtered": {
                "filter": {
                  "script": {
                    "script": "if(_source.transactions.size<3) return false;fromDate=Date.parse('yyyy-MM-dd',fromDateParam);toDate=Date.parse('yyyy-MM-dd',toDateParam);count=0;for(d in _source.transactions){docsDate=Date.parse('yyyy-MM-dd',d.get('date'));if(docsDate>=fromDate && docsDate<=toDate){count++};if(count==3){return true;}};return false;",
                    "params": {
                      "fromDateParam":"2014-10-24",
                      "toDateParam":"2015-10-24"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    The actual range filter is an "optimization" for those documents where none of the dates matches. So that, this document (with no dates in the range) will not reach the more costly script filter.

    The script itself first checks if the number of transactions is less than 3. If it is, don't bother doing all the date checks and return false. If it's more than 3 then take each date and compare with the parameters. As soon as a count of 3 is reached stop looking at the rest of the dates and return true.

    0 讨论(0)
提交回复
热议问题