Faceted search with aggregations

I am trying to do faceted search with aggregation (which I think is the way to do, suggestions are welcome).

so the query below is sending the search term with the aggs.
POST events/event/_search { "query": { "multi_match": { "query": "phone", "fields": [ "title", "description" ], } }, "aggs": { "Brand Filter": { "terms": { "field": "brand.keyword", "size": 80 } }, "size Filter": { "terms": { "field": "size.keyword", "size": 80 } } } }

however, as an example of what i have similar as facet search

Capture

so if the user selects lets say Samsung and Apple. Where does these appear in query.

Thanks.

You need to use the selected content in a bool query using term filter.

If you do want to keep all the options even when the results are filtered after queried, see this

There's an example of how to make a filter in the link above as well.

so this is my current query I tried with filter. I am getting error saying

`"reason": "[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",`

{ "query":{ "multi_match": { "query": "phone", "fields": ["title","description"] }, "bool":{ "filter":[ {"term":{"brand":"samsung"}} ] } } }

In addition to this, I would like to know how can I pass an array as "brand": ["samsung","Apple"]

Thanks,

There you go:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "phone",
            "fields": [
              "title",
              "description"
            ]
          }
        }
      ],
      "filter": [
        {
          "terms": {
            "brand": [
              "samsung", "Apple"
            ]
          }
        }
      ]
    }
  }
}

if my filter is just one word like samsung or Apple. it works fine but if its a phrase like general social survey. even though I have that exact phrase in my index, it gives me zero result. cant the filter be a phrase.

Yes, it can be a phrase. If you could share the piece of code you're writing and a data sample, it would be easier to help you.

`{

"query": {
"bool": {
"must":
{
"multi_match": {
"query": " social survey",
"fields": [
"title", "abstract"
]
}
},
"filter":[
{"match_phrase": {"survey":{"query": "Aboriginal Peoples survey"}}},
{"match_phrase": {"subjects":{"query": "population characteristics"}}}
]
}
}
}`

i ended up using match_phrase because the filter query that is selected is a phrase instead of one term. so using terms even though I was able to pass multiple values i was only able to pass a term not a phrase. but now here, each query of the match_phrase is a faceted search.

Basically, i have a list of survey and list of search, user can select multiple surveys and subjects, how do I handle that.

Thanks for your patience.

What you are doing in there is that it's looking for a "Aboriginal Peoples survey" survey AND "population characteristics" subject. Maybe it is the reason why you're not getting anything when fetching it.
Maybe you need to rearrange the query structure to look for one thing or another.
You can wrap this filter in a should clause in a bool query and set the minimum_should_match option to 1.

What you are suggesting is, it will give results if the document matches either survey or the subjects.
I would like those documents to match who has this survey and this subject both, but here I can only pass a single phrase of subject and survey, I would like to be able to pass an array. I will be storing it as an search template so later on I can just give it a list of subjects and list of surveys.
any suggestions would be helpful. thanks for your time.

Sorry about the delay on getting back to you on this.

So, you can git the terms a try, like I suggest in here:

"filter": [
  {
    "terms": {
      "brand": [
        "phrase 1", "phrase 2"
      ]
    }
  }
]

If you want to combine more filters, you just need to add them to the filter array and you will get the "AND" result as you wish, like this:

"filter": [
  {
    "terms": {
      "survey": [
        "phrase 1", "phrase 2"
      ]
    }
  },
  {
    "terms": {
      "subjects": [
        "phrase 1", "phrase 2"
      ]
    }
  }
]

Not sure if this is what you're aiming but let me know in any case.

I have tried this. The issue with this is since its terms, its searches for "phrase" and "1" in subjects however, I want it to match the subjects that has exactly" phrase 1". but match_phrase is not able to take an array. I am actually converting these query in a search template. so the subjects filter should be able to take a list .

You can use {{#toJson}}subjects{{/toJson}}
See here how to use it.

Hope you find it useful.

where do I put the field I want it to search then. I am trying to figure out the difference between what you gave and this {{#join}}emails{{/join}}

There's an example in the documentation.

The difference is that join will send the values passed through param as a string separated by commas and json will send the values as an array.

so now I am using it like this:

   `{

"source": {
"query": {
"bool":{
"must":[
{"match_phrase": {"subjects.en": "{{#join}}subjects{{/join}}"}},
{"match_phrase": {"survey.title.en": "{{#join}}surveys{{/join}}"}}
]
}
}
},
"params": {
"subjects": [ "Social Well-being", "Social Networks" ],
"surveys": ["General Social Survey"]
}
}`

but its giving empty result. I want to use match phrase because it needs to match the phrase provided exactly.

Instead of passing only the terms as a parameter, you might need to pass the whole match phrase condition.

I think you could do something like this:

"source": {
  "query": {
    "bool":{
      "must":[
        {{#join}}subjects{{/join}}
        {{#join}}surveys{{/join}}
      ]
    }
  }
},
"params": {
  "subjects": [
    {"match_phrase": {"subjects.en": "Social Well-being"}},
    {"match_phrase": {"subjects.en": "Social Networks"}},
  ],
  "surveys": [
    {"match_phrase": {"subjects.en": "General Social Survey"}}
  ]
}

This is giving error,

`error": {
"root_cause": [
  {
    "type": "parsing_exception",
    "reason": "Could not parse inline template",
    "line": 6,
    "col": 9
  }
],
"type": "x_content_parse_exception",
"reason": "[6:9] [search_template] failed to parse field [source]",
"caused_by": {
  "type": "parsing_exception",
  "reason": "Could not parse inline template",
  "line": 6,
  "col": 9,
  "caused_by": {
    "type": "json_parse_exception",
    "reason": "Unexpected character ('{' (code 123)): was expecting double-quote to start field name\n at [Source: org.elasticsearch.transport.netty4.ByteBufStreamInput@3c783eba; line: 6, column: 11]",
    "suppressed": [
      {
        "type": "illegal_state_exception",
        "reason": "Failed to close the XContentBuilder",
        "caused_by": {
          "type": "i_o_exception",
          "reason": "Unclosed object or array found"`

Try this:


  "source": "{\"query\": {\"bool\":{\"must\":[{{#toJson}}subjects{{/toJson}},{{#toJson}}surveys{{/toJson}}]}}}",
  "params": {
    "subjects": [
      {"match_phrase": {"subjects.en": "Social Well-being"}},
      {"match_phrase": {"subjects.en": "Social Networks"}}
    ],
    "surveys": [
      {"match_phrase": {"survey.title.en": "General Social Survey"}}
    ]
  }


I tested this in my own index and it should work fine.

would there be "and" or "OR" relation between subjects and surveys?
and what about between subjects itself. will there be an "OR"

All "and". This is what you wanted in the first place, isn't it?