1

I have a 60-bit (minutes in an hour) field that I would like to aggregate with a bit-wise or operator so that the end result is a bit set if any of the contributing values had that bit set.

The representation of the bit field isn't determined yet, but it would be nice to have it be somewhat compact as there are a lot of records entering the aggregation.

Say we have three documents with a bitfield taking the binary values: 0001, 1001, 1100. A bit-wise or aggregation would combine them to the value 1101 - a bit is true if that bit is set in any value. Much like a sum aggregation but bit-wise operation instead.

I've considered a bit-position array (position present if bit is set) but it gets a little verbose.

Scripted metric aggregation could be possible but I'm a little at a loss of how to implement it.

Scripted metric agg would look something like this broken painless code:

"aggs": {
    "profit": {
      "scripted_metric": {
        "init_script": "minagg = 0L", 
        "map_script": "minagg = minagg | minutes",
     }
   }
 }

Thanks for looking.

SEngstrom
  • 321
  • 1
  • 10
  • Are you looking for something like this? https://stackoverflow.com/a/54988461/4604579 – Val Jan 21 '21 at 04:08
  • Can you share a sample document and pseudo query you'd like to make? – Val Jan 21 '21 at 07:51
  • That's a cool answer - not recognizing the scripting - looks like a java flavor? Will update the question with an example. – SEngstrom Jan 21 '21 at 15:04
  • Yes, scripting in Elasticsearch is done in the [Painless language](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-painless.html) which is a built on top of Java – Val Jan 21 '21 at 15:05
  • I'm pretty new to it and couldn't find the functions you were using there. I'll keep looking - many thanks for the input. – SEngstrom Jan 21 '21 at 15:24
  • 1
    The full API is available here: https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-api-reference.html – Val Jan 21 '21 at 15:24

1 Answers1

0

The scripted metric aggregation handles this. With an index with the following mapping...

"mappings": {
  "default": {
    "dynamic": "strict",
    "properties": {
      "bitfield": {
        "type": "long"
      }
    }
  }
}

... this aggregation delivers the or'd values:

POST /bitfield/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "orfield": {
      "scripted_metric": {
        "init_script": "state.agg = 0L",
        "map_script": "state.agg |= doc.bitfield.value",
        "combine_script": "return state.agg",
        "reduce_script": "long total = 0L; for (a in states) {total |= a} return total"
      }
    }
  }
}
SEngstrom
  • 321
  • 1
  • 10