0

我一直想知道如何在将术语过滤器实际添加到过滤后的查询之前检查搜索参数是否不为空。从我对弹性搜索的有限经验来看,我似乎必须提前构建我的确切查询。

如果我使用 Node / Mongo,我知道我可以做一些类似的事情

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);
    }
 });    

并且在角度上,我已经为弹性搜索构建了一个查询,只要填写了所有参数,它就可以正常工作。我想我的问题是如何根据用户填写的参数有条件地和动态地构建过滤查询。

即用户A 填写了国家和公司,但没有填写工资。因此,工资不会作为术语过滤器包含在内。

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 }
                    }
                ]
             }

       }
 }

谢谢大家!

4

1 回答 1

0

您描述的 Node/Mongo 一直在做的是 Elasticsearch 查询的方式。

所以你的 JS 代码可能看起来像:

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 }, ...);
于 2015-10-10T20:47:40.600 回答