【问题标题】:Elasticsearch NEST client creating multi-field fields with completionElasticsearch NEST 客户端创建带有完成的多字段字段
【发布时间】:2015-05-17 08:49:57
【问题描述】:

我正在尝试在我的某些领域创建一些完成建议。我的文档类如下所示:

[ElasticType(Name = "rawfiles", IdProperty = "guid")]
public class RAW
{
    [ElasticProperty(OmitNorms = true, Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String, Store = true)]
    public string guid { get; set; }

    [ElasticProperty(OmitNorms = true, Index = FieldIndexOption.Analyzed, Type = FieldType.String, Store = true, IndexAnalyzer = "def_analyzer", SearchAnalyzer = "def_analyzer_search", AddSortField = true)]
    public string filename { get; set; }

    [ElasticProperty(OmitNorms = true, Index = FieldIndexOption.Analyzed, Type = FieldType.String, Store = true, IndexAnalyzer = "def_analyzer", SearchAnalyzer = "def_analyzer_search")]
    public List<string> tags { get { return new List<string>(); } }
}

这就是我尝试创建完成字段的方式

public bool CreateMapping(ElasticClient client, string indexName)
{
    IIndicesResponse result = null;
    try
    {
        result = client.Map<RAW>(
                c => c.Index(indexName)
                    .MapFromAttributes()
                    .AllField(f => f.Enabled(false))
                    .SourceField(s => s.Enabled())
                    .Properties(p => p
                        .Completion(s => s.Name(n => n.tags.Suffix("comp"))
                                    .IndexAnalyzer("standard")
                                    .SearchAnalyzer("standard")
                                    .MaxInputLength(20)
                                    .Payloads()
                                    .PreservePositionIncrements()
                                    .PreserveSeparators())
                        .Completion(s2 => s2.Name(n=>n.filename.Suffix("comp"))
                                    .IndexAnalyzer("standard")
                                    .SearchAnalyzer("standard")
                                    .MaxInputLength(20)
                                    .Payloads()
                                    .PreservePositionIncrements()
                                    .PreserveSeparators())
                        )
                   );
    }
    catch (Exception)
    {

    }

    return result != null && result.Acknowledged;
}

我的问题是这只是创建一个名为“comp”的完成字段。我的印象是这将创建两个完成字段,一个名为 filename.comp,另一个名为 tags.comp。

然后我在SO question 上尝试了答案,但这使事情变得更糟,因为现在我的两个字段仅被映射为完成字段。

为了清楚起见,我想创建一个具有数据、排序和完成文件的多字段(字段)。很像this example中的那个

【问题讨论】:

    标签: elasticsearch autocomplete nest autosuggest


    【解决方案1】:

    这是您如何重现您所附article 的自动完成示例。

    我的简单类(我们将在Name 属性上实现自动完成)

    public class Document
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

    要在 NEST 中创建多字段映射,我们必须以这种方式定义映射:

    var indicesOperationResponse = client.CreateIndex(descriptor => descriptor
        .Index(indexName)
        .AddMapping<Document>(m => m
            .Properties(p => p.MultiField(mf => mf
                .Name(n => n.Name)
                .Fields(f => f
                    .String(s => s.Name(n => n.Name).Index(FieldIndexOption.Analyzed))
                    .String(s => s.Name(n => n.Name.Suffix("sortable")).Index(FieldIndexOption.NotAnalyzed))
                    .String(s => s.Name(n => n.Name.Suffix("autocomplete")).IndexAnalyzer("shingle_analyzer"))))))
        .Analysis(a => a
            .Analyzers(b => b.Add("shingle_analyzer", new CustomAnalyzer
            {
                Tokenizer = "standard",
                Filter = new List<string> {"lowercase", "shingle_filter"}
            }))
            .TokenFilters(b => b.Add("shingle_filter", new ShingleTokenFilter
            {
                MinShingleSize = 2,
                MaxShingleSize = 5
            }))));
    

    让我们索引一些文档:

    client.Index(new Document {Id = 1, Name = "Tremors"});
    client.Index(new Document { Id = 2, Name = "Tremors 2: Aftershocks" });
    client.Index(new Document { Id = 3, Name = "Tremors 3: Back to Perfection" });
    client.Index(new Document { Id = 4, Name = "Tremors 4: The Legend Begins" });
    client.Index(new Document { Id = 5, Name = "True Blood" });
    client.Index(new Document { Id = 6, Name = "Tron" });
    client.Index(new Document { Id = 7, Name = "True Grit" });
    client.Index(new Document { Id = 8, Name = "Land Before Time" });
    client.Index(new Document { Id = 9, Name = "The Shining" });
    client.Index(new Document { Id = 10, Name = "Good Burger" });
    
    client.Refresh();
    

    现在,我们准备写前缀查询:)

    var searchResponse = client.Search<Document>(s => s
        .Query(q => q
            .Prefix("name.autocomplete", "tr"))
        .SortAscending(sort => sort.Name.Suffix("sortable")));
    

    这个查询会得到我们

    Tremors 2: Aftershocks
    Tremors 3: Back to Perfection
    Tremors 4: The Legend Begins
    Tron
    True Blood
    True Grit
    

    希望这会对你有所帮助。

    最近,来自 NEST 的人为 NEST 和 elasticsearch 准备了很棒的 tutorial。有一部分是关于suggestions,应该对你很有用。

    【讨论】:

    • 有没有办法通过从属性映射来做到这一点?
    • 我不这么认为。看看github.com/elastic/elasticsearch-net/pull/827.
    • 哎哟......如果是这种情况,那么我必须更改 6 种类型的映射函数,每种类型都有 20 多个字段......
    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 2022-12-14
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2017-12-22
    相关资源
    最近更新 更多