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