MM-6992 Added highlighting to elasticsearch results (#8861)
* MM-6992 Added highlighting to elasticsearch results * Added a unique type for post search matches * Fixed Elasticsearch matches not being sent through API
Этот коммит содержится в:
коммит произвёл
Carlos Tadeu Panato Junior
родитель
6d8140337e
Коммит
226d4b2ac8
@@ -341,7 +341,7 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
posts, err := c.App.SearchPostsInTeam(terms, c.Session.UserId, c.Params.TeamId, isOrSearch)
|
results, err := c.App.SearchPostsInTeam(terms, c.Session.UserId, c.Params.TeamId, isOrSearch)
|
||||||
|
|
||||||
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
|
elapsedTime := float64(time.Since(startTime)) / float64(time.Second)
|
||||||
metrics := c.App.Metrics
|
metrics := c.App.Metrics
|
||||||
@@ -355,8 +355,10 @@ func searchPosts(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
results = model.MakePostSearchResults(c.App.PostListWithProxyAddedToImageURLs(results.PostList), results.Matches)
|
||||||
|
|
||||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
w.Write([]byte(c.App.PostListWithProxyAddedToImageURLs(posts).ToJson()))
|
w.Write([]byte(results.ToJson()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
10
app/post.go
10
app/post.go
@@ -621,7 +621,7 @@ func (a *App) DeletePostFiles(post *model.Post) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bool) (*model.PostList, *model.AppError) {
|
func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bool) (*model.PostSearchResults, *model.AppError) {
|
||||||
paramsList := model.ParseSearchParams(terms)
|
paramsList := model.ParseSearchParams(terms)
|
||||||
|
|
||||||
esInterface := a.Elasticsearch
|
esInterface := a.Elasticsearch
|
||||||
@@ -656,7 +656,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
|
|||||||
|
|
||||||
// If the processed search params are empty, return empty search results.
|
// If the processed search params are empty, return empty search results.
|
||||||
if len(finalParamsList) == 0 {
|
if len(finalParamsList) == 0 {
|
||||||
return model.NewPostList(), nil
|
return model.MakePostSearchResults(model.NewPostList(), nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only allow the user to search in channels they are a member of.
|
// We only allow the user to search in channels they are a member of.
|
||||||
@@ -666,7 +666,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
postIds, err := a.Elasticsearch.SearchPosts(userChannels, finalParamsList)
|
postIds, matches, err := a.Elasticsearch.SearchPosts(userChannels, finalParamsList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -684,7 +684,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return postList, nil
|
return model.MakePostSearchResults(postList, matches), nil
|
||||||
} else {
|
} else {
|
||||||
if !*a.Config().ServiceSettings.EnablePostSearch {
|
if !*a.Config().ServiceSettings.EnablePostSearch {
|
||||||
return nil, model.NewAppError("SearchPostsInTeam", "store.sql_post.search.disabled", nil, fmt.Sprintf("teamId=%v userId=%v", teamId, userId), http.StatusNotImplemented)
|
return nil, model.NewAppError("SearchPostsInTeam", "store.sql_post.search.disabled", nil, fmt.Sprintf("teamId=%v userId=%v", teamId, userId), http.StatusNotImplemented)
|
||||||
@@ -712,7 +712,7 @@ func (a *App) SearchPostsInTeam(terms string, userId string, teamId string, isOr
|
|||||||
|
|
||||||
posts.SortByCreateAt()
|
posts.SortByCreateAt()
|
||||||
|
|
||||||
return posts, nil
|
return model.MakePostSearchResults(posts, nil), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
type ElasticsearchInterface interface {
|
type ElasticsearchInterface interface {
|
||||||
Start() *model.AppError
|
Start() *model.AppError
|
||||||
IndexPost(post *model.Post, teamId string) *model.AppError
|
IndexPost(post *model.Post, teamId string) *model.AppError
|
||||||
SearchPosts(channels *model.ChannelList, searchParams []*model.SearchParams) ([]string, *model.AppError)
|
SearchPosts(channels *model.ChannelList, searchParams []*model.SearchParams) ([]string, model.PostSearchMatches, *model.AppError)
|
||||||
DeletePost(post *model.Post) *model.AppError
|
DeletePost(post *model.Post) *model.AppError
|
||||||
TestConfig(cfg *model.Config) *model.AppError
|
TestConfig(cfg *model.Config) *model.AppError
|
||||||
PurgeIndexes() *model.AppError
|
PurgeIndexes() *model.AppError
|
||||||
|
|||||||
@@ -4278,6 +4278,10 @@
|
|||||||
"id": "ent.elasticsearch.search_posts.search_failed",
|
"id": "ent.elasticsearch.search_posts.search_failed",
|
||||||
"translation": "Search failed to complete"
|
"translation": "Search failed to complete"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "ent.elasticsearch.search_posts.parse_matches_failed",
|
||||||
|
"translation": "Failed to parse search result matches"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "ent.elasticsearch.search_posts.unmarshall_post_failed",
|
"id": "ent.elasticsearch.search_posts.unmarshall_post_failed",
|
||||||
"translation": "Failed to decode search results"
|
"translation": "Failed to decode search results"
|
||||||
|
|||||||
@@ -2127,6 +2127,17 @@ func (c *Client4) SearchPosts(teamId string, terms string, isOrSearch bool) (*Po
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchPosts returns any posts with matching terms string, including .
|
||||||
|
func (c *Client4) SearchPostsWithMatches(teamId string, terms string, isOrSearch bool) (*PostSearchResults, *Response) {
|
||||||
|
requestBody := map[string]interface{}{"terms": terms, "is_or_search": isOrSearch}
|
||||||
|
if r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/posts/search", StringInterfaceToJson(requestBody)); err != nil {
|
||||||
|
return nil, BuildErrorResponse(r, err)
|
||||||
|
} else {
|
||||||
|
defer closeBody(r)
|
||||||
|
return PostSearchResultsFromJson(r.Body), BuildResponse(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DoPostAction performs a post action.
|
// DoPostAction performs a post action.
|
||||||
func (c *Client4) DoPostAction(postId, actionId string) (bool, *Response) {
|
func (c *Client4) DoPostAction(postId, actionId string) (bool, *Response) {
|
||||||
if r, err := c.DoApiPost(c.GetPostRoute(postId)+"/actions/"+actionId, ""); err != nil {
|
if r, err := c.DoApiPost(c.GetPostRoute(postId)+"/actions/"+actionId, ""); err != nil {
|
||||||
|
|||||||
40
model/post_search_results.go
Обычный файл
40
model/post_search_results.go
Обычный файл
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PostSearchMatches map[string][]string
|
||||||
|
|
||||||
|
type PostSearchResults struct {
|
||||||
|
*PostList
|
||||||
|
Matches PostSearchMatches `json:"matches"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePostSearchResults(posts *PostList, matches PostSearchMatches) *PostSearchResults {
|
||||||
|
return &PostSearchResults{
|
||||||
|
posts,
|
||||||
|
matches,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *PostSearchResults) ToJson() string {
|
||||||
|
copy := *o
|
||||||
|
copy.PostList.StripActionIntegrations()
|
||||||
|
b, err := json.Marshal(©)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostSearchResultsFromJson(data io.Reader) *PostSearchResults {
|
||||||
|
var o *PostSearchResults
|
||||||
|
json.NewDecoder(data).Decode(&o)
|
||||||
|
return o
|
||||||
|
}
|
||||||
Ссылка в новой задаче
Block a user