首页 > 解决方案 > 如何在 ElasticSearch Nest 中定义动态自定义字段?

问题描述

具有以下数据结构。

public class Contact
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public List<Phone> Phones { get; set; }
}

public class Phone
{
    public string AreaCode { get; set; }
    public string PhoneNumber { get; set; }
    public bool IsMobile { get; set; }
}

我创建了一个简单的实用程序函数来构建自定义术语查询。我正在尝试使用字符串定义 fieldExpression。我想用 stringExpression 参数代替“p.Phone.First().PhoneNumber”。那可能吗?

private TermQuery BuildTermQuery(string stringExpression, string value)
{
    // Expression<Func<Contact, string>> fieldExpression = p => p.Phone.First().PhoneNumber;
    Expression<Func<Contact, string>> fieldExpression = p => $"{stringExpression}";

    var query = new TermQuery
    {
        Field = new Field(fieldExpression),
        Value = value
    };

    return query;
}

如果有其他方法可以做到这一点,请告诉我。提前感谢您的帮助

标签: c#elasticsearchnest

解决方案


使用Expression<Func<T, TProp>>lambda 表达式访问成员T旨在帮助对属性进行类型化访问,因此传递表达式字符串有点违背目的:)

可以只将字符串传递给Field构造函数,或者使用从字符串到的隐式转换Field

Field f = "my_field";
    
Field f2 = new Field("my_field_2");

如果您知道您使用的是什么大小写约定,则可以将nameof()其与属性名称结合使用,然后相应地大小写。例如,对于骆驼案

Field f3 = nameof(ElasticContact.Property).ToCamelCase();

public class ElasticContact
{
    public string Property {get;set;}
}

public static class Extensions
{
    public static string ToCamelCase(this string s)
    {
        if (string.IsNullOrEmpty(s) || char.IsLower(s, 0))
            return s;

        var array = s.ToCharArray();
        array[0] = char.ToLowerInvariant(array[0]);
        return new string(array);
    }
}

编辑

对于嵌套对象字段,仍然可以传递字符串

Field f = "phone.phoneNumber";

在您的示例中,您可以将表达式传递给方法,并避免使用字符串

private static void Main()
{
    var query = BuildTermQuery<Contact, string>(c => c.Phones.First().PhoneNumber, "123456");
}

private static TermQuery BuildTermQuery<T, TProp>(Expression<Func<T, TProp>> fieldExpression, string value)
{
    var query = new TermQuery
    {
        Field = new Field(fieldExpression),
        Value = value
    };

    return query;
}

如果您真的想从字符串表达式构建成员表达式,您可以引用Microsoft.CodeAnalysis.CSharp.Scripting并将表达式字符串评估为表达式委托。


推荐阅读