ElasticSearch (NEST) 按编号搜索

Rub*_*aus 2 elasticsearch nest

如果这是一个基本问题,我提前道歉 - 我对 ElasticSearch 非常陌生,需要了解很多。

现在,我正在尝试实现一个基本的关键字搜索来搜索所有索引列,并且我得到了一些带有特定字段的奇怪结果,Year. 我有一定数量的文件,我知道应该从结果中返回,如果我搜索“2014”,它们都会成功返回。如果我只搜索“14”,什么都不会返回,如果我添加了一个通配符(例如*14),那么我会得到一个结果,因为它没有Year在搜索中使用而是从该Description领域。

我 100% 肯定这是我在查询结构上做错的事情,所以有什么提示吗?顺便说一句,如果有人可以提供建议的地方来了解有关使用 NEST 的 Elastic 的更多信息,那将非常有帮助。他们的文档有点缺乏,您必须了解如何使用 Elastic 才能使大部分内容有意义,而由于我不知道,所以我只能磕磕绊绊。

这是 的结构ElasticListing

    public long Id { get; set; }

    public string Brand { get; set; }

    public string Manufacturer { get; set; }

    public string ActiveTags { get; set; }

    public string Description { get; set; }

    public int Year { get; set; }

    public string Location { get; set; }
Run Code Online (Sandbox Code Playgroud)

我在 NEST 中使用的搜索结构是这样的,keyword“2014”在哪里(没有引号):

var response = this.ElasticClient.Search<ElasticListing>(s => s
            .AllTypes()
            .Query(query => query
                .Bool(b => b
                    .Must(must => must
                        .QueryString(qs => qs.Query(keyword))
                    )
                )                   
            )
            .Size(pageSize)
            .Explain()              
        );
Run Code Online (Sandbox Code Playgroud)

Rus*_*Cam 5

您要执行的是termYearElasticsearch 中的字段进行查询

var response = client.Search<ElasticListing>(s => s
    .AllTypes()
    .Query(query => query
        .Term(f => f.Year, 2014)
    )
    .Size(pageSize)
    .Explain()
);
Run Code Online (Sandbox Code Playgroud)

查看文档的编写查询部分

为了对Year字段执行通配符查询,需要将其索引为keyword数据类型keyword在索引时不分析输入,这可能是我们希望将数值索引为“字符串”)。

默认情况下,NEST 会将Year字段序列化为JSON 中的数字,而 Elasticsearch 会将其映射为数字数据类型。即使使用 NEST 的自动映射,NEST 也会推断 的integer数据类型映射Year,以匹配Int32属性的 CLR 类型。因此,我们需要覆盖这个推断的映射以确保Year被索引为keyword数据类型。

这是一个完整的例子

private static void Main()
{
    var defaultIndex = "listings"; 
    var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    // Make this example re-runnable. You likely want to remove this :)
    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);     

    client.CreateIndex(defaultIndex, c => c
        .Mappings(m => m
            .Map<ElasticListing>(mm => mm
                .AutoMap()
                .Properties(p => p
                    // override the default inferred mapping for Year
                    .Keyword(k => k
                        .Name(n => n.Year) 
                    )
                )
            )
        )
    );

    client.IndexMany(new [] {
        new ElasticListing { Id = 1, Year = 2012 },
        new ElasticListing { Id = 2, Year = 2013 },
        new ElasticListing { Id = 3, Year = 2014 },
        new ElasticListing { Id = 4, Year = 1014 },      
    });

    client.Refresh(defaultIndex);

    var pageSize = 10;

    // returns only document with Id = 3
    var response = client.Search<ElasticListing>(s => s
        .AllTypes()
        .Query(query => query
            .Term(f => f.Year, 2014)
        )
        .Size(pageSize)
        .Explain()
    );

    // returns documents with Ids = 3 and 4
    response = client.Search<ElasticListing>(s => s
        .AllTypes()
        .Query(query => query
            .Wildcard(f => f.Year, "*14", rewrite:(MultiTermQueryRewrite)null)
        )
        .Size(pageSize)
        .Explain()
    );
}

public class ElasticListing
{
    public long Id { get; set; }
    public string Brand { get; set; }
    public string Manufacturer { get; set; }
    public string ActiveTags { get; set; }
    public string Description { get; set; }
    public int Year { get; set; }
    public string Location { get; set; }
}
Run Code Online (Sandbox Code Playgroud)