【发布时间】:2016-10-03 13:18:04
【问题描述】:
我想为我的用户创建一个搜索引擎。假设用户类是:
public class User
{
public string Code { get; set; }
public string Name { get; set; }
}
我的数据库中有这样的用户:
(1) new User { Code = "XW1234", Name = "John Doe" },
(2) new User { Code = "AD4567", Name = "Jane Doe" }
所以:
当我的查询是:“doe”(注意小写)时,我想查看 (1) 和 (2)
当我的查询是:“4”时,我想查看 (1) 和 (2)
当我的查询是:“x”我想看 (1)
当我的查询是:“ja”我想看 (2)
我想在 SQL 中与like %doe% 类似地工作。请不要介意查询长度 - 我将使用最少 3 个字母。这只是一个例子。
我有一个使用通配符的解决方案 - 有效,但性能很差。
我试图将索引配置为使用 ngram 标记器,但没有成功 - 我收到一个空集合。
我也检查了这个(“开始”方法): https://www.elastic.co/guide/en/elasticsearch/guide/current/_index_time_search_as_you_type.html 没有成功。
请提供 C# 代码。我不知道我是否正确翻译了 Elastic 搜索 json。
编辑 根据第一条评论,我尝试了这个:
private const string DefaultIndexName = "test";
private const string ElasticSearchServerUri = @"http://192.168.99.100:32769";
private static readonly IndexName UsersIndexName = "users";
public IElasticClient CreateElasticClient()
{
var settings = CreateConnectionSettings();
var client = new ElasticClient(settings);
var studentsIndexDescriptor = new CreateIndexDescriptor(UsersIndexName)
.Mappings(ms => ms
.Map<User>(m => m
.Properties(ps => ps
.String(s => s
.Name(n => n.Code)
.Analyzer("substring_analyzer")))));
client.CreateIndex(UsersIndexName, descriptor => studentsIndexDescriptor
.Settings(s => s
.Analysis(a => a
.Analyzers(analyzer => analyzer
.Custom("substring_analyzer", analyzerDescriptor => analyzerDescriptor.Tokenizer("standard").Filters("lowercase", "substring")))
.TokenFilters(tf => tf
.NGram("substring", filterDescriptor => filterDescriptor.MinGram(2).MaxGram(15))))));
return client;
}
private static ConnectionSettings CreateConnectionSettings()
{
var uri = new Uri(ElasticSearchServerUri);
var settings = new ConnectionSettings(uri);
settings
.DefaultIndex(DefaultIndexName);
return settings;
}
我使用了这个查询:
public IEnumerable<User> Search(string query)
{
var result = elasticClient.Search<User>(descriptor => descriptor
.Query(q => q
.QueryString(queryDescriptor => queryDescriptor.Query(query).Fields(fs => fs.Fields(f1 => f1.Code)))));
return result.Documents;
}
没用。
我尝试了代码:“1234”和“5678”。我尝试用“23”、“5”查询 - 没有结果。 当我搜索“1234”时,它会返回正确的用户。
【问题讨论】:
-
您需要使用 ngram 令牌过滤器。这个答案可能会有所帮助:stackoverflow.com/questions/34331249/…
-
“请提供 C# 代码”。你都尝试了些什么?你能用 NGram 标记器/NGram 标记过滤器展示你的尝试吗?
-
@RussCam - 我添加了一个例子
标签: c# .net elasticsearch nest