【问题标题】:NEST Sort by Text fieldNEST 按文本字段排序
【发布时间】:2018-04-09 08:03:20
【问题描述】:

我正在尝试编写一个使用 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 };
    }
}

响应与此报告一致失败:

{"error":{"root_cause":[{"type":"illegal_argument_exception","re​​ason":"Fielddata 默认情况下在文本字段上禁用。在 [电子邮件] 上设置 fielddata=true 为了通过反转反转来将字段数据加载到内存中 指数。请注意,这可能会占用大量内存。 或者使用关键字字段 相反。"}],"type":"search_phase_execution_exception","re​​ason":"all 碎片 失败","阶段":"查询","分组":true,"failed_shards":[{"shard":0,"index":"xxxx","node":"xxxx","re​​ason":{ "type":"illegal_argument_exception","re​​ason":"Fielddata 默认情况下在文本字段上禁用。在 [电子邮件] 上设置 fielddata=true 为了通过反转反转来将字段数据加载到内存中 指数。请注意,这可能会占用大量内存。 或者使用关键字字段。"}}]},"status":400}

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

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

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

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

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

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

【问题讨论】:

  • 映射是什么样的?映射是否按预期拾取覆盖属性上的属性?
  • @RussCam -- 是的。描述符将 Email 属性显示为 FieldData 设置为 true。

标签: c# elasticsearch nest


【解决方案1】:

根据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 };
}

解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    相关资源
    最近更新 更多