elasticsearch nest支持函数核心函数中的过滤器

时间:2014-05-06 00:56:39

标签: elasticsearch nest

我目前正在尝试在NEST中实现“function_score”查询,其中的函数仅在过滤器匹配时应用。

看起来不像FunctionScoreFunctionsDescriptor支持添加过滤器。这个功能是否会很快添加?



这是我希望能够实现的一个超级基本示例:

  1. 使用基本分数运行ES查询
  2. 浏览功能列表,并在其中添加过滤器匹配的第一个分数
  3. "function_score": {
        "query": {...},  // base ES query
        "functions": [
            {
                "filter": {...},
                "script_score": {"script": "25"}
            },
            {
                "filter": {...},
                "script_score": {"script": "15"}
            }      
        ],
        "score_mode": "first",  // take the first script_score where the filter matches
        "boost_mode": "sum"  // and add this to the base ES query score
    }
    

    我目前正在使用Elasticsearch v1.1.0和NEST v1.0.0-beta1预发布。

    谢谢!

2 个答案:

答案 0 :(得分:5)

它已经实施:

_client.Search<ElasticsearchProject>(s => 
            s.Query(q=>q
                .FunctionScore(fs=>fs.Functions(
                    f=>f
                        .ScriptScore(ss=>ss.Script("25"))
                        .Filter(ff=>ff.Term(t=>t.Country, "A")),
                    f=> f
                        .ScriptScore(ss=>ss.Script("15"))
                        .Filter(ff=>ff.Term("a","b")))
                .ScoreMode(FunctionScoreMode.first)
                .BoostMode(FunctionBoostMode.sum))));

答案 1 :(得分:3)

Udi的答案对我不起作用。似乎在新版本(v 2.3,C#)中ScoreFunctionsDescriptor类没有Filter()方法。

但我找到了解决方案。您可以提供IScoreFunction的数组。为此,您可以使用new FunctionScoreFunction()或使用我的助手类:

class CustomFunctionScore<T> : FunctionScoreFunction
    where T: class
{
    public CustomFunctionScore(Func<QueryContainerDescriptor<T>, QueryContainer> selector, double? weight = null)
    {
        this.Filter = selector.Invoke(new QueryContainerDescriptor<T>());
        this.Weight = weight;
    }
}

使用这个类,可以通过这种方式应用过滤器(这只是一个例子):

        SearchDescriptor<BlobPost> searchDescriptor = new SearchDescriptor<BlobPost>()
            .Query(qr => qr
                .FunctionScore(fs => fs
                    .Query(q => q.Bool(b => b.Should(s => s.Match(a => a.Field(f => f.FirstName).Query("john")))))
                    .ScoreMode(FunctionScoreMode.Max)
                    .BoostMode(FunctionBoostMode.Sum)
                    .Functions(
                        new[] 
                        {
                            new CustomFunctionScore<BlobPost>(q => q.Match(a => a.Field(f => f.Id).Query("my_id")), 10),
                            new CustomFunctionScore<BlobPost>(q => q.Match(a => a.Field(f => f.FirstName).Query("john")), 10),
                        }
                    )
                )
            );