NEST 按文本字段排序

Rob*_*don 4 c# elasticsearch nest

我正在尝试编写一个使用 NEST 并将搜索功能保持在其自己的有界上下文中的搜索模块。

为此,我进行了以下用户个人资料搜索:

public class UserProfileSearch : IUserProfileSearch
{
    ...

    public async Task<PagedItems<UserProfileModel>> FindAsync(string searchTerm, int skip, int take)
    {
        var client = _elasticClientProvider.GetClient();
        var response = await client.SearchAsync<ElasticUserProfileModel>(s => s
            .Index(_elasticConfiguration.GetIndex())
            .From(skip).Size(take)
            .Query(q => q.MultiMatch(m => m.Fields(f => f
                .Field(u => u.Email)
                .Field(u => u.FirstName)
                .Field(u => u.LastName))
                .Query(searchTerm)))
            .Sort(q => q.Ascending(u => u.Email)));
        var count = await client.CountAsync<ElasticUserProfileModel>(s => s.Index(_elasticConfiguration.GetIndex()));
        return new PagedItems<UserProfileModel> { Items = response.Documents.Cast<UserProfileModel>().ToArray(), Total = count.Count };
    }
}
Run Code Online (Sandbox Code Playgroud)

响应与此报告一致失败:

在 [email] 上设置 fielddata=true 以通过反转倒排索引将 fielddata 加载到内存中。请注意,这可能会占用大量内存。或者改用关键字字段。"}}]},"status":400}

但是,我已经按照报告中的建议做了,但同样的错误不断发生。我已经定义

public class ElasticUserProfileModel : UserProfileModel
{
    [Text(Fielddata = true)] public override string Email { get => base.Email; set => base.Email = value; }
}
Run Code Online (Sandbox Code Playgroud)

这应该正是报告所要求的。我正在ElasticUserProfileModel每个端到端测试期间使用 重建索引。

我也尝试过使用Keyword属性而不是Text属性,但这会产生完全相同的错误。

如果我按Id(数字)而不是排序Email,则没有错误。但这是一个明显不太有用的搜索。

有没有简单的方法来解决这个问题?

Rob*_*don 8

根据https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/multi-fields.html上的文档,我发现 POCO 字符串会自动映射到关键字和文本域。该Suffix()扩展方法是使字符串排序工作所需要的所有我。

我删除了ElasticUserProfileModel派生类,FindAsync()方法变成了

public async Task<PagedItems<UserProfileModel>> FindAsync(string searchTerm, int skip, int take)
{
    var client = _elasticClientProvider.GetClient();
    var response = await client.SearchAsync<UserProfileModel>(s => s
        .Index(_elasticConfiguration.GetIndex())
        .From(skip).Size(take)
        .Query(q => q.MultiMatch(m => m.Fields(f => f
            .Field(u => u.Email)
            .Field(u => u.FirstName)
            .Field(u => u.LastName))
            .Query(searchTerm)))
        .Sort(q => q.Ascending(u => u.Email.Suffix("keyword"))));
    var count = await client.CountAsync<UserProfileModel>(s => s.Index(_elasticConfiguration.GetIndex()));
    return new PagedItems<UserProfileModel> { Items = response.Documents.ToArray(), Total = count.Count };
}
Run Code Online (Sandbox Code Playgroud)

这解决了问题。