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 */
}
}
}
ファセットの結果として、次のようになります。
- ジャンル(842)
- 98(47)
- 51(30)
- 24(29)
- 46(28)
私は次のようなものを手に入れることを期待していますが:
- ジャンル1(842)
- ジャンル2(47)
- ジャンル3(30)
- ジャンル4(29)
- ジャンル5(28)
私は何を間違えますか?Nestとそのファセットでネストされたフィールドを使用する正しい方法を確認する場所はどこですか?
ありがとうございました。
更新1:
私はそれがトークナイザー/アナライザーと関係があることを発見しました。ジャンル名にスペースやダッシュがない場合は、すべて正常に機能します。分析されていないインデックス属性も試しました
[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);
注釈の何が問題だったのかわかりません。インデックス設定に注釈を使用するために必要な追加の構成はありますか?