我如何在不过滤结果的情况下影响Elasticsearch的结果分数?

问题描述 投票:1回答:1

我希望附近的工作在搜索结果中更高,但是每当我尝试根据距离更改分数时,我都会得到零结果。我根本不想按距离筛选作业,而只更改结果的相关性。

我尝试过:

        var response = await client.SearchAsync<JobIndex>(x => x
            .Index(nameof(JobIndex).ToLower())
            .Source(sf => sf.Includes(i => i.Fields(fields)))
            .From(query.Skip.GetValueOrDefault(0))
            .Size(query.Take.GetValueOrDefault(25))
            .Query(q =>
                q.Bool(b => b.MustNot(mustNotQueries))
                && q.Bool(b => b.Must(mustQueries))
                && q.Bool(b => b.Should(shouldQueries))
                && q.FunctionScore(c => c
                    .Query(s => s.MatchAll())
                    .Functions(scoreFunctions)
                )
              ), cancellationToken);

还有:

        var response = await client.SearchAsync<JobIndex>(x => x
            .Index(nameof(JobIndex).ToLower())
            .Source(sf => sf.Includes(i => i.Fields(fields)))
            .From(query.Skip.GetValueOrDefault(0))
            .Size(query.Take.GetValueOrDefault(25))
            .Query(q =>
                q.Bool(b => b.MustNot(mustNotQueries))
                && q.Bool(b => b.Must(mustQueries))
                && q.Bool(b => b.Should(shouldQueries))
              )
            .Query(q => q.FunctionScore(c => c
               .Query(s => s.MatchAll())
               .Functions(scoreFunctions)
            ))
            , cancellationToken);

但是我什么也没回来。如果删除了使用“ scoreFunctions”的部件,则查询工作正常。这是我正在使用的评分功能:

scoreFunctions.Add(new LinearGeoDecayFunction
    {
        Origin = new GeoLocation(result.Latitiude, result.Longitude),
        Field = Infer.Field<JobIndex>(g => g.LatLong),
        Scale = Distance.Miles(50),
        Decay = 0.5
    });

如何编写此查询?

elasticsearch nest
1个回答
0
投票

您应将主查询移至函数分数查询,并为总和设置boost mode,以便添加更多“点”以使其接近原点。

这里是示例应用程序。经过elasticsearch 7.4.0和NEST 7.3.1测试]

    static async Task Main(string[] args)
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var connectionSettings = new ConnectionSettings(pool);
        connectionSettings
            .DefaultIndex("documents")
            //do not use in production
            .PrettyJson()
            .DisableDirectStreaming();

        var client = new ElasticClient(connectionSettings);

        await client.Indices.DeleteAsync("documents");

        await client.Indices.CreateAsync("documents", 
            d => d.Map(m => m.AutoMap<City>()));

        await client.IndexManyAsync(new List<City>
        {
            new City
            {
                Id = "1", Name = "Warszawa", Country = "Poland", Location = new GeoLocation(52.237049, 21.017532)
            },
            new City
            {
                Id = "2", Name = "Kraków", Country = "Poland", Location = new GeoLocation(50.049683, 19.944544)
            },
            new City
            {
                Id = "3", Name = "Wieliczka", Country = "Poland", Location = new GeoLocation(49.987061, 20.064796)
            },
            new City
            {
                Id = "4", Name = "Berlin", Country = "Germany", Location = new GeoLocation(52.520008, 13.404954)
            }
        });

        await client.Indices.RefreshAsync();

        var searchResponse = await client.SearchAsync<City>(s => s
            .Query(q => q.FunctionScore(fs =>
                fs
                    .Query(qq =>
                        qq.Match(mm => mm.Field(f => f.Country).Query("Poland")))
                    .BoostMode(FunctionBoostMode.Sum)
                    .Functions(new[]
                    {
                        new LinearGeoDecayFunction
                        {
                            Origin = new GeoLocation(
                                50.049683, 19.944544),
                            Field = Field<City>(
                                f => f.Location),
                            Scale = Distance.Kilometers(100),
                            Decay = 0.5
                        }
                    }))));

        foreach (var hit in searchResponse.Hits)
        {
            System.Console.WriteLine($"Name: {hit.Source.Name} Score: {hit.Score}");
        }
    }

    public class City
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Country { get; set; }
        [GeoPoint]
        public GeoLocation Location { get; set; }
    }
}

输出

Name: Kraków Score: 1.3566749
Name: Wieliczka Score: 1.3013793
Name: Warszawa Score: 0.35667494

希望有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.