gpt4 book ai didi

elasticsearch - 使用 Elasticsearch C# Mpdreamz/NEST 客户端的嵌套字段上的 Facet

转载 作者:行者123 更新时间:2023-11-29 02:53:51 26 4
gpt4 key购买 nike

如何使用 Mpdreamz/NEST Elasticsearch 客户端根据嵌套字段的属性列出分面?

我查看了 Nest 文档,但不清楚该怎么做。

这是我试过的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Nest;

namespace Demo
{
class Program
{
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
[ElasticProperty(Index = FieldIndexOption.analyzed, Type = FieldType.nested)]
public List<Genre> Genres { get; set; }
public int Year { get; set; }
}

public class Genre
{
// public int Id { get; set; }
[ElasticProperty(Index = FieldIndexOption.analyzed)]
public string GenreTitle { get; set; }
}

static void Main(string[] args)
{
var setting = new ConnectionSettings("localhost", 9200);
setting.SetDefaultIndex("default_index");
var client = new ElasticClient(setting);

// delete previous index with documents
client.DeleteIndex<Movie>();

// put documents to the index
var genres = new List<Genre>();
for (var i = 0; i < 100; i++)
genres.Add(new Genre { GenreTitle = string.Format("Genre {0}", i) });
for (var i = 0; i < 1000; i++)
{
client.Index(new Movie
{
Id = i,
Description = string.Format("Some movie description {0}", i),
Title = string.Format("Movie Title {0}", i),
Year = 1980 + (i % 10),
Genres = genres.OrderBy(x => Guid.NewGuid()).Take(10).ToList()
});
}

// query with facet on nested field property genres.genreTitle
var queryResults = client.Search<Movie>(x => x
.From(0)
.Size(10)
.MatchAll()
.FacetTerm(t => t
.OnField(f => f.Year)
.Size(30))
.FacetTerm(t => t
.Size(5)
.OnField(f => f.Genres.Select(f1 => f1.GenreTitle) )
)
);

var yearFacetItems = queryResults.FacetItems<FacetItem>(p => p.Year);
foreach (var item in yearFacetItems)
{
var termItem = item as TermItem;
Console.WriteLine(string.Format("{0} ({1})", termItem.Term, termItem.Count));
}
/* Returns:
1989 (90)
1988 (90)
1986 (90)
1984 (90)
1983 (90)
1981 (90)
1980 (90)
1987 (89)
1982 (89)
1985 (88)
and it's fine! */

var genresFacetItems = queryResults.FacetItems<FacetItem>(p => p.Genres.Select(f => f.GenreTitle));
foreach (var item in genresFacetItems)
{
var termItem = item as TermItem;
Console.WriteLine(string.Format("{0} ({1})", termItem.Term, termItem.Count));
}
/* Return soemthing:
genre (842)
98 (47)
51 (30)
24 (29)
46 (28)
and it's BAD!
I expect the Genre Title to be listed as
string, not as some strange integer */
}
}
}

作为 facet 的结果,我得到:

  • 类型 (842)
  • 98 (47)
  • 51 (30)
  • 24 (29)
  • 46 (28)

虽然我希望得到类似的东西:

  • 类型 1 (842)
  • 类型 2 (47)
  • 类型 3 (30)
  • 类型 4 (29)
  • 类型 5 (28)

我做错了什么?在哪里可以检查在 Nest 中使用嵌套字段的正确方法以及它们的分面?

谢谢。

更新 1:

我发现它与分词器/分析器有关。如果流派名称没有空格或破折号 - 一切正常。我也试过 not-analyzed 索引属性

[ElasticProperty(Index = FieldIndexOption.not_analyzed)]
public string GenreTitle { get; set; }

但是没用

更新 2:我在之前的索引删除后立即添加了流畅的索引映射而不是注释,例如:

var settings = new IndexSettings();
var typeMapping = new TypeMapping("movies");
var type = new TypeMappingProperty
{
Type = "string",
Index = "not_analyzed",
Boost = 2.0
// Many more options available
};
typeMapping.Properties = new Dictionary<string, TypeMappingProperty>();
typeMapping.Properties.Add("genres.genreTitle", type);
settings.Mappings.Add(typeMapping);
client.CreateIndex("default_index", settings);

现在不确定注释有什么问题。使用注释进行索引设置是否需要任何额外的配置?

最佳答案

嗨,这里是 NEST 的作者,

如果使用注解需要手动调用

var createIndex = client.CreateIndex("default_index", new IndexSettings { });
client.Map<Movie>();

在第一次调用索引之前。 Nest 不会在每个索引调用上应用映射,因为这会产生太多开销。如果索引不存在,旧版本的 elasticsearch 只会创建索引,不需要 CreateIndex 调用。

因为你想在嵌套类型上分面,你必须将 .Nested("genres") 传递给分面调用。

你看到的数字实际上是嵌套的 docids :)

这是我修改后的有效的 program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using Nest;

namespace Demo
{
class Program
{
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
[ElasticProperty(Type=FieldType.nested)]
public List<Genre> Genres { get; set; }
public int Year { get; set; }
}

public class Genre
{
// public int Id { get; set; }
[ElasticProperty(Index = FieldIndexOption.not_analyzed)]
public string GenreTitle { get; set; }
}

static void Main(string[] args)
{
var setting = new ConnectionSettings("localhost", 9200);
setting.SetDefaultIndex("default_index");
var client = new ElasticClient(setting);

// delete previous index with documents
client.DeleteIndex<Movie>();

var createIndexResult = client.CreateIndex("default_index", new IndexSettings { });
var mapResult = client.Map<Movie>();

// put documents to the index
var genres = new List<Genre>();
for (var i = 0; i < 100; i++)
genres.Add(new Genre { GenreTitle = string.Format("Genre {0}", i) });
for (var i = 0; i < 1000; i++)
{
client.Index(new Movie
{
Id = i,
Description = string.Format("Some movie description {0}", i),
Title = string.Format("Movie Title {0}", i),
Year = 1980 + (i % 10),
Genres = genres.OrderBy(x => Guid.NewGuid()).Take(10).ToList()
});
}

// query with facet on nested field property genres.genreTitle
var queryResults = client.Search<Movie>(x => x
.From(0)
.Size(10)
.MatchAll()
.FacetTerm(t => t
.OnField(f => f.Year)
.Size(30))
.FacetTerm(t => t
.Size(5)
.OnField(f => f.Genres.Select(f1 => f1.GenreTitle))
.Nested("genres")
)
);

var yearFacetItems = queryResults.FacetItems<FacetItem>(p => p.Year);
foreach (var item in yearFacetItems)
{
var termItem = item as TermItem;
Console.WriteLine(string.Format("{0} ({1})", termItem.Term, termItem.Count));
}

var genresFacetItems = queryResults.FacetItems<FacetItem>(p => p.Genres.Select(f => f.GenreTitle));
foreach (var item in genresFacetItems)
{
var termItem = item as TermItem;
Console.WriteLine(string.Format("{0} ({1})", termItem.Term, termItem.Count));
}

}
}
}

关于elasticsearch - 使用 Elasticsearch C# Mpdreamz/NEST 客户端的嵌套字段上的 Facet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13218346/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com