我使用NEST与Elasticsearch合作。我尝试将所有字符串字段分解为标记。同时为tokininiz使用ngram。但是,在提示查询时,我总是得到0结果。
我的班级与api一起工作。
public class Elasticsearch
{
string index = "video-materials";
ElasticClient client;
public Elasticsearch()
{
var settings = new ConnectionSettings(new Uri("http://localhost:9200"));
client = new ElasticClient(settings);
if (client.IndexExists(index).Exists)
{
client.DeleteIndex(index);
}
var nGramFilters = new List<string> { "lowercase", "asciifolding", "nGram_filter" };
var resp = client.CreateIndex(index, c => c
.Mappings(m => m
.Map<ElasticVideoMaterial>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.OriginalTitle)
.Fields(f => f
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(256)
)
.Text(tt => tt
.Name("ngram")
.Analyzer("ngram_analyzer")
)
)
)
)
)
)
.Settings(s => s
.Analysis(a => a
.Analyzers(anz => anz
.Custom("ngram_analyzer", cc => cc
.Filters(nGramFilters)
.Tokenizer("ngram_tokenizer")))
.Tokenizers(tz => tz
.NGram("ngram_tokenizer", td => td
.MinGram(3)
.MaxGram(3)
.TokenChars(TokenChar.Letter, TokenChar.Digit)
)
)
)
)
);
}
public void Index(IEnumerable<ElasticVideoMaterial> models)
{
foreach(var model in models)
{
client.Index(model,i=>i.Index(index));
}
}
public void Search(string query)
{
var resp = client.Search<ElasticVideoMaterial>(i => i
.Query(q => q
.Match(m => m
.Field(f => f.OriginalTitle.Suffix("ngram"))
.Query("Hob")
)
)
.Index(index)
).Documents.ToList();
}
}
我总是再次创建一个索引,然后我索引对象列表。为此,请使用Index()方法。这是我的索引类。
public class ElasticVideoMaterial
{
public int ID { get; set; }
public string Title { get; set; }
public string OriginalTitle { get; set; }
public float? KinopoiskRating { get; set; }
public float? Imdb { get; set; }
public int Duration { get; set; }
public List<string> GenreTitles { get; set; }
public List<string> CountryNames { get; set; }
public DateTime? ReleaseDate { get; set; }
public List<string> TranslationTitles { get; set; }
public List<string> FilmMakerNames { get; set; }
public List<string> ActorNames { get; set; }
public List<string> ThemeNames { get; set; }
public CompletionField Suggest { get; set; }
}
但是当我尝试使用Search()方法获得结果时,我得到0结果。 (写过“滚刀”后,我希望收到名字中包含“霍比特人”的电影)
ngram_analyzer
用于分析搜索请求的查询输入,但此分析器不用于分析索引请求的OriginalTitle
输入。
您只需将分析器配置为在索引文档时用于OriginalTitle
字段,该文档可以使用attribute mapping或fluent mapping指定。例如,流畅的映射
var client = new ElasticClient();
if (client.IndexExists(defaultIndex).Exists)
client.DeleteIndex(defaultIndex);
var nGramFilters = new List<string> { "lowercase", "asciifolding", "nGram_filter" };
var resp = client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<ElasticVideoMaterial>(mm => mm
.AutoMap()
.Properties(p => p
.Text(t => t
.Name(n => n.OriginalTitle)
.Fields(f => f
.Keyword(k => k
.Name("keyword")
.IgnoreAbove(256)
)
.Text(tt => tt
.Name("ngram")
.Analyzer("ngram_analyzer")
)
)
)
)
)
)
.Settings(s => s
.Analysis(a => a
.Analyzers(anz => anz
.Custom("ngram_analyzer", cc => cc
.Filters(nGramFilters)
.Tokenizer("ngram_tokenizer")))
.Tokenizers(tz => tz
.NGram("ngram_tokenizer", td => td
.MinGram(3)
.MaxGram(3)
.TokenChars(TokenChar.Letter, TokenChar.Digit)
)
)
)
)
);
var searchResponse = client.Search<ElasticVideoMaterial>(i => i
.Query(q => q
.Match(m => m
.Field(f => f.OriginalTitle.Suffix("ngram"))
.Query("Hob")
)
)
);
这将OriginalTitle
设置为multi-field并在ngram
下创建一个名为OriginalTitle
的多场,它将在索引时间和搜索时间使用ngram_analyzer
。