【问题标题】:Use ElasticSearch Nest 5.6 to script sort by a boolean value使用 ElasticSearch Nest 5.6 脚本按布尔值排序
【发布时间】:2018-01-03 04:13:24
【问题描述】:

我在 ElasticSearch 5.6 中有一个对象,它使用带有以下属性的 Nest:

[Object(Name = "UserFlags")]
public List<long> UserFlags { get; set; }

我有一个脚本排序,它以下列方式使用此字段:

sorts.Add(new ScriptSort
{
    Type = "boolean",
    Order = SortOrder.Ascending,
    Script = new InlineScript("doc['UserFlags'].value.indexOf(userID) > -1")
    {
        Lang = "groovy",
        Params = new Dictionary<string, object>
        {
            { "userID", user.ID }
        }
    }
});

这个脚本总是抛出异常并且无法排序(它没有返回任何结果,因为脚本有问题)。按其他属性排序可以正常工作,甚至其他脚本排序也可以按预期工作:

sorts.Add(new ScriptSort
{
    Order = SortOrder.Ascending,
    Type = "number",
    Script = new InlineScript("doc['TotalGalleryCount'].value - doc['ClosedGalleryCount'].value")
});

我做错了什么? Nest 文档非常稀少。

编辑

如果我将脚本修改为:

sorts.Add(new ScriptSort
{
    Type = "string",
    Order = SortOrder.Ascending,
    Script = new InlineScript(string.Format("doc['UserFlags'].values.contains({0})", user.ID))
});

然后脚本执行并返回结果。但是,在我的单元测试中,排序似乎并没有影响结果。 (注意在脚本排序之后还有一个额外的排序sorts.Add(new SortField { Field = "Filename", Order = SortOrder.Ascending });。)

输入:[“c.jpg”(假)、“a.jpg”(真)、“b.jpg”(假)、“a.jpg”(假)]

预期:[“a.jpg”(假)、“b.jpg”(假)、“c.jpg”(假)、“a.jpg”(真)]

实际:[“a.jpg”(假),“a.jpg”(真),“b.jpg”(假),“c.jpg”(假)]

这几乎就像它以错误的顺序应用排序一样,但它们是这样添加的:

sorts.Add(new ScriptSort
{
    Type = "string",
    Order = SortOrder.Ascending,
    Script = new InlineScript(string.Format("doc['UserFlags'].values.contains({0})", user.ID))
});
sorts.Add(new SortField { Field = "Filename", Order = SortOrder.Ascending });

应该正确执行它们...

【问题讨论】:

标签: c# .net elasticsearch groovy nest


【解决方案1】:

所以在从 groovy 切换到 painless 并尝试了一堆内置的 painless 功能(不起作用)之后,我的最终解决方案是:

//HACK: Yes, this is ugly, but painless does not like the contains() or indexOf() functions
var script = "for (int i = 0; i < doc['UserFlags'].values.length; i++) if (doc['UserFlags'].values[i] == {0}) return true; return false;";
script = string.Format(script, user.ID);

sorts.Add(new ScriptSort
{
    Type = "string",
    Order = defaultOrder,
    Script = new InlineScript(script)
});
sorts.Add(new SortField { Field = "Filename", Order = determinedOrder });

我们使用 painless 而不是 groovy,因为我们的服务器不允许 groovy 脚本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多