How to sort by a property with NEST when the name is given as string? Please help

This is a C# snippet of what I am trying to do:

string MyProperty = "MyPropertyName";
var MyOrder = SortOrder.Ascending;
Func<SortDescriptor<MyClass>, Nest.IPromise<IList<ISort>>> Sorting;
        Sorting = sort => sort
                    .Field(so => so
                        .Field(f => f.GetType().GetProperty(MyProperty))
                        .Order(MyOrder)
                    );

MyClass is just a model for the data, so the structure is fixed for all documents.
MyProperty would be the sort column I get back from my client, it is a string and it matches exactly the property names on the C# object.

The critical point here is that I try to get the property with reflection. That doesn't seem to work. I need a way to infer the property from a string, as the frontend will provide what column of the output table it will sort by.

I looked at the docu for inference, but that seems overly complicated for this (if it even applies to that case). I don't want to remap anything, the client knows the property names from my c# object and only those are sent back as columns to sort by.

Am I doing something wrong here? It doesn't work for some reason. This snippet goes into my NEST query. It works when I just use a static property without the reflection like:
.Field(f => f.MyProperty)

I just want to use a string to identify the property, and reflection seemed to be the easiest way to do that.

I just get an "all shards failed" error from the elastic server, which isn't very helpful in figuring out what is wrong.

I am using a 7.4.1 elastic instance and the latest NEST (7.4.2).

Bump
Is there really no one who can helps with this?

You can pass the string directly to .Field(...)

var client  = new ElasticClient();

client.Search<MyClass>(s => s
	.Sort(so => so
		.Field(fs => fs
			.Field("foo")
			.Order(SortOrder.Ascending)
		)
	)
);

public class MyClass
{
    public string Foo {get;set;}
}

which yields

{
    "sort": [{
        "foo": {
            "order": "asc"
        }
    }]
}

Check out the documentation on field inference and sorting.

This unfortunately doesn't work.

I use a model that has all the properties decorated with PropertyName attributes that are then used by the elastic serializer. This means that the property name the client sees looks like this:

FooBar

But elastic would only know

foo_bar

While the NEST client takes care of that nicely in other cases, I just use the lambda expression and directly say what property I want, in this particular case it seems to work against me.

That's why I tried to get the actual property with reflections. If I just use the name, it doesn't match.

I actually found a working solution now:

string FieldName
Func<SortDescriptor<ES_DesignInfoWrapper>, Nest.IPromise<IList>> Sorting;
System.Reflection.PropertyInfo property = typeof(ES_DesignInfoWrapper).GetProperty(FieldName);
string name = ((ElasticsearchPropertyAttributeBase)(property.GetCustomAttributes(typeof(ElasticsearchPropertyAttributeBase), false)[0])).Name;
Sorting = sort => sort
.Field(so => so
.Field(name)
.Order()
);

This gets the database name from the attribute of the property and uses it to adress the field.

Casting the attribute as the attribute base class allows me to use that for different fields like Text and Number etc. Some special sauce is needed if you want to use this for nested fields, but it works well for the basic types.

Does someone have a more elegant solution?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.