2

I have to index email messages, each having a list of recipients, like this:

{
"To":[{"name":"John", "email":"[email protected]"}, {"name":"Jane", "email":"[email protected]"}],
"Body": "Blah blah blah"
}

I want to search in the body texts and perform aggregations over messages that have more than one recipient only. I tried to use token_count datatype and value_count aggregation, but neither seems to be applicable. Is there a way to define a filter over multi-value counter?

2 Answers 2

1

Actually, I guess your To field is a nested field. I don't see why shouldn't be like that if you want to really associate a name with an email address. Otherwise it would just be a list of names and a list of addresses without any association between them.

If your field is a nested one then its mapping should be this one:

    "To": {
      "type": "nested",
      "include_in_parent": true, 
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string"
        }
      }
    }

Then the query to search for a certain number of email addresses:

{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "filter": {
        "script": {
          "script": {
            "inline": "doc['To.name'].size() > counter",
            "params": {
              "counter": 1
            }
          }
        }
      }
    }
  }
}

Even if the field is not nested the query above still applies.

Sign up to request clarification or add additional context in comments.

Comments

0

Maybe a Script Query can work for you:

"bool" : {
    "must" : {
        // query on body
        ...
    },
    "filter" : {
        "script" : {
            "script" : {
                "inline" : "doc['To.name'].size() > param1"
                "params" : {
                    "param1" : 1
                }
            }
        }
    }
}

But dont forget to enable scripting: https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html#enable-dynamic-scripting

2 Comments

Turns out the proper way is doc['To.name'].size() or doc['To.name'].values.size(). The length method is not there anymore, probably since Elastic moved to Groovy.
Yeah. Sorry for that. You had the working solution anyway :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.