0

I've been wondering how to go about checking if a search parameter is not empty before actually adding that term filter to a filtered query. From my limited experience with elasticsearch, it seems like I have to build my exact query ahead of time.

If I were using Node / Mongo, I know that I could do something along the lines of

var searchTerms = {};
if(req.body.country){
  searchTerm['user.country'] = req.body.country;
}

if(req.body.company){
  searchTerm['user.company'] = req.body.company;
}

if(req.body.salary){
  searchTerm['user.salary'] = req.body.salary;
}

Users.find(searchTerm)
  .exec(function(err, users) {
    if(!err){
      res.send(200, users);    
    }
    else{
      res.send(200, err);
    }
 });    

And in angular I've built a query for elasticsearch that works correctly as long as all parameters are filled in. I guess my question is how to conditionally and dynamically build filtered query based on parameters that have been filled in by the user.

i.e. User A fills out country and company but leaves out salary. therefore, salary wouldn't be included as a term filter.

client.search({
  index: 'firebase',
  type: 'user',
  body: {
    "query": {
       "filtered" : {
           "query" : {
               "match_all" : {}
             },
             "filter": {
                "and": [
                    {
                      "term": { "country" : searchParameters.country }
                    },
                    {
                      "term": { "company" : searchParameters.company }
                    },
                    {
                      "term": { "salary" : searchParameters.salary }
                    }
                ]
             }

       }
 }

Thank you all in advance!

K.B. Choi
  • 13
  • 1
  • 8

1 Answers1

0

What you have been doing for Node/Mongo that you describe is the way to go for Elasticsearch queries.

So your JS code might look something like:

var filters = [];
var fields = ['country', 'company', 'salary',...]; // or some kind of hash to map req fields to elasticsearch fields if appropriate
for(var k = 0; k < fields.length; k++) {
    if(req.body[fields[k]]) {
        var termq = { term : {} };
        termq.term[fields[k]] = req.body[fields[k]];
        filters.push(termq);
    }
}

var query = {
    filtered : {
        query : { match_all : {} },
        filter : filters.length ? { and : filters } : {}
    }
};

client.search({ index: ..., type: ..., body: query }, ...);
eemp
  • 1,156
  • 9
  • 17
  • Awesome man...thanks a bunch! I'm glad it's pretty much the same as the code I was doing in node/mongo! I'm going to try something similar once I get back to work! – K.B. Choi Oct 11 '15 at 01:40