Elasticsearch(NEST)按数字进行搜索



如果这是一个基本问题,我会提前道歉 - 我对Elasticsearch非常陌生,并且可以接受很多。

目前,我正在尝试实现一个基本的关键字搜索,该搜索搜索所有索引列,并且通过特定字段Year获得了一些奇怪的结果。我知道应该从结果中回来一定数量的文档,如果我搜索" 2014",所有这些文档都会成功地回来。如果我只搜索" 14",那么什么都没有回来,如果我添加了一个通配符(例如*14(,那么我会得到一个结果,因为它在搜索中没有使用Year,而是拉了它来自Description字段。

我是100%肯定的,这是我在查询结构上做错了什么,所以有任何技巧吗?顺便说一句,如果有人可以提供建议的地方,以了解有关Nest的弹性的更多信息,那将非常有帮助。他们的文档缺乏一些文档,您必须了解如何将其使用弹性才能使大多数人变得有意义,而且由于我没有,所以我绊倒了。

这是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; }

我在巢中使用的搜索结构就是这样,其中 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()              
        );

您想要执行的是eLasticsearch中的Year字段上的term查询

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

看文档的写作查询部分。

为了在Year字段上执行通配符查询,需要将其索引为keyword数据类型(keyword不在索引时间分析输入,这可能是我们想要的数值值为索引的内容。"细绳"(。

默认情况下,Nest将序列化Year字段为JSON中的数字,而Elasticsearch将推断为数字数据类型的映射。即使使用Nest的自动化,Nest也会推断integer的CC_13数据类型映射,以匹配该属性的CLR类型Int32。因此,我们需要覆盖此推断的映射,以确保将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; }
}

最新更新