Elasticsearch 2.0 类搜索查询
Elastic search 2.0 search like query
这是我的模型:
[ElasticsearchType(Name = "projectmodel")]
public class ProjectModel
{
public string name { get; set; }
public string description { get; set; }
[Nested]
[JsonProperty("taskmodels")]
public List<TaskModel> taskmodels { get; set; }
}
public class TaskModel
{
public string title { get; set; }
public string description { get; set; }
}
我使用以下代码在主对象和嵌套对象中进行搜索。
var searchResults = client.Search<ProjectModel>(
body => body.Query(
query => query.Bool(
bq => bq.Should(
q => q.Match(p => p.Field(f => f.name).Boost(6).Query(keyword)),
q => q.Match(p => p.Field(f => f.description).Boost(6).Query(keyword)),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.description")
)
)
),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.title")
)
)
)
)
)
).Size(MAX_RESULT)
);
这会毫无问题地搜索对象。但我需要为 searchText 输入确切的词才能得到结果。
举个例子:姓名 - "Science and technology"
如果我用技术搜索,它return是记录。但是如果我用techno搜索,它没有return记录。我该如何解决这个问题?
您可以在您的字段上添加 match_phrase_prefix 查询。
Match_phrase_prefix 将获取您搜索查询中的最后一个标记,并对其进行短语前缀匹配。令牌的顺序很重要。如果您想在文本中的任何位置进行搜索,那么您将需要创建 n-grams 和 edge_grams 个标记
var searchResults = _elasticClient.Search<ProjectModel>(
body => body.Query(
query => query.Bool(
bq => bq.Should(
q=> q.MatchPhrasePrefix(p=>p.Field(f=>f.name).Query(keyword)) --> note
q => q.Match(p => p.Field(f => f.name).Boost(6).Query(keyword)),
q => q.MatchPhrasePrefix(p => p.Field(f => f.description).Boost(6).Query(keyword)),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.description")
)
)
),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.title")
)
)
)
)
)
).Size(MAX_RESULT)
);
匹配、匹配短语和匹配短语前缀之间的区别
假设有一个文档,字段 "description" : "science and technology"
此文本在单独的标记 ["science" ,"and","technology"] 中被分解,并在倒排索引中出现。
如果要查找 "science technology" ,可以使用匹配查询。因为单词的匹配顺序无关紧要,所以当你搜索 "technology science" 时你也会得到文档。它只匹配标记。
如果顺序对您很重要,那么使用 match_phrase "science and technology" 只会 return 文档。
如果你想搜索部分句子 "science and techno" 然后使用 match_phrase_prefix 。前缀匹配仅在最后一个标记上执行,因此您无法搜索 "scie and techno"。为此,还有其他选项,如 edge-ngrams 和 ngrams
这是我的模型:
[ElasticsearchType(Name = "projectmodel")]
public class ProjectModel
{
public string name { get; set; }
public string description { get; set; }
[Nested]
[JsonProperty("taskmodels")]
public List<TaskModel> taskmodels { get; set; }
}
public class TaskModel
{
public string title { get; set; }
public string description { get; set; }
}
我使用以下代码在主对象和嵌套对象中进行搜索。
var searchResults = client.Search<ProjectModel>(
body => body.Query(
query => query.Bool(
bq => bq.Should(
q => q.Match(p => p.Field(f => f.name).Boost(6).Query(keyword)),
q => q.Match(p => p.Field(f => f.description).Boost(6).Query(keyword)),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.description")
)
)
),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.title")
)
)
)
)
)
).Size(MAX_RESULT)
);
这会毫无问题地搜索对象。但我需要为 searchText 输入确切的词才能得到结果。
举个例子:姓名 - "Science and technology"
如果我用技术搜索,它return是记录。但是如果我用techno搜索,它没有return记录。我该如何解决这个问题?
您可以在您的字段上添加 match_phrase_prefix 查询。
Match_phrase_prefix 将获取您搜索查询中的最后一个标记,并对其进行短语前缀匹配。令牌的顺序很重要。如果您想在文本中的任何位置进行搜索,那么您将需要创建 n-grams 和 edge_grams 个标记
var searchResults = _elasticClient.Search<ProjectModel>(
body => body.Query(
query => query.Bool(
bq => bq.Should(
q=> q.MatchPhrasePrefix(p=>p.Field(f=>f.name).Query(keyword)) --> note
q => q.Match(p => p.Field(f => f.name).Boost(6).Query(keyword)),
q => q.MatchPhrasePrefix(p => p.Field(f => f.description).Boost(6).Query(keyword)),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.description")
)
)
),
sh => sh.Nested(n => n.Path(p => p.taskmodels).Query(nq => nq.Match(
m => m.Query(keyword).Field("taskmodels.title")
)
)
)
)
)
).Size(MAX_RESULT)
);
匹配、匹配短语和匹配短语前缀之间的区别
假设有一个文档,字段 "description" : "science and technology" 此文本在单独的标记 ["science" ,"and","technology"] 中被分解,并在倒排索引中出现。
如果要查找 "science technology" ,可以使用匹配查询。因为单词的匹配顺序无关紧要,所以当你搜索 "technology science" 时你也会得到文档。它只匹配标记。
如果顺序对您很重要,那么使用 match_phrase "science and technology" 只会 return 文档。
如果你想搜索部分句子 "science and techno" 然后使用 match_phrase_prefix 。前缀匹配仅在最后一个标记上执行,因此您无法搜索 "scie and techno"。为此,还有其他选项,如 edge-ngrams 和 ngrams