summaryrefslogtreecommitdiffstats
path: root/app/post.go
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2017-05-18 16:26:52 +0100
committerHarrison Healey <harrisonmhealey@gmail.com>2017-05-18 11:26:52 -0400
commit0db5e3922fd5045b3f7f518ad65e42138f0325c4 (patch)
treee225a7191de7915a3da3716601ddb415c4f26979 /app/post.go
parent2bbedd9def2a782f370fb5280994ea0ecbf8a7c7 (diff)
downloadchat-0db5e3922fd5045b3f7f518ad65e42138f0325c4.tar.gz
chat-0db5e3922fd5045b3f7f518ad65e42138f0325c4.tar.bz2
chat-0db5e3922fd5045b3f7f518ad65e42138f0325c4.zip
PLT-6472: Basic Elastic Search implementation. (#6382)
* PLT-6472: Basic Elastic Search implementation. This currently supports indexing of posts at create/update/delete time. It does not support batch indexing or reindexing, and does not support any entities other than posts yet. The purpose is to more-or-less replicate the existing full-text search feature but with some of the immediate benefits of using elastic search. * Alter settings for AWS compatability. * Remove unneeded i18n strings.
Diffstat (limited to 'app/post.go')
-rw-r--r--app/post.go108
1 files changed, 93 insertions, 15 deletions
diff --git a/app/post.go b/app/post.go
index bf61bafb2..341287cf4 100644
--- a/app/post.go
+++ b/app/post.go
@@ -125,6 +125,11 @@ func CreatePost(post *model.Post, teamId string, triggerWebhooks bool) (*model.P
rpost = result.Data.(*model.Post)
}
+ esInterface := einterfaces.GetElasticSearchInterface()
+ if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) {
+ go esInterface.IndexPost(rpost, teamId)
+ }
+
if einterfaces.GetMetricsInterface() != nil {
einterfaces.GetMetricsInterface().IncrementPostCreate()
}
@@ -308,6 +313,17 @@ func UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError
} else {
rpost := result.Data.(*model.Post)
+ esInterface := einterfaces.GetElasticSearchInterface()
+ if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) {
+ go func() {
+ if rchannel := <-Srv.Store.Channel().GetForPost(rpost.Id); rchannel.Err != nil {
+ l4g.Error("Couldn't get channel %v for post %v for ElasticSearch indexing.", rpost.ChannelId, rpost.Id)
+ } else {
+ esInterface.IndexPost(rpost, rchannel.Data.(*model.Channel).TeamId)
+ }
+ }()
+ }
+
sendUpdatedPostEvent(rpost)
InvalidateCacheForChannelPosts(rpost.ChannelId)
@@ -484,6 +500,11 @@ func DeletePost(postId string) (*model.Post, *model.AppError) {
go DeletePostFiles(post)
go DeleteFlaggedPosts(post.Id)
+ esInterface := einterfaces.GetElasticSearchInterface()
+ if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) {
+ go esInterface.DeletePost(post.Id)
+ }
+
InvalidateCacheForChannelPosts(post.ChannelId)
return post, nil
@@ -509,27 +530,84 @@ func DeletePostFiles(post *model.Post) {
func SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bool) (*model.PostList, *model.AppError) {
paramsList := model.ParseSearchParams(terms)
- channels := []store.StoreChannel{}
- for _, params := range paramsList {
- params.OrTerms = isOrSearch
- // don't allow users to search for everything
- if params.Terms != "*" {
- channels = append(channels, Srv.Store.Post().Search(teamId, userId, params))
+ esInterface := einterfaces.GetElasticSearchInterface()
+ if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableSearching && utils.IsLicensed && *utils.License.Features.ElasticSearch) {
+ finalParamsList := []*model.SearchParams{}
+
+ for _, params := range paramsList {
+ params.OrTerms = isOrSearch
+ // Don't allow users to search for "*"
+ if params.Terms != "*" {
+ // Convert channel names to channel IDs
+ for idx, channelName := range params.InChannels {
+ if channel, err := GetChannelByName(channelName, teamId); err != nil {
+ l4g.Error(err)
+ } else {
+ params.InChannels[idx] = channel.Id
+ }
+ }
+
+ // Convert usernames to user IDs
+ for idx, username := range params.FromUsers {
+ if user, err := GetUserByUsername(username); err != nil {
+ l4g.Error(err)
+ } else {
+ params.FromUsers[idx] = user.Id
+ }
+ }
+
+ finalParamsList = append(finalParamsList, params)
+ }
}
- }
- posts := model.NewPostList()
- for _, channel := range channels {
- if result := <-channel; result.Err != nil {
- return nil, result.Err
+ // We only allow the user to search in channels they are a member of.
+ userChannels, err := GetChannelsForUser(teamId, userId)
+ if err != nil {
+ l4g.Error(err)
+ return nil, err
+ }
+
+ postIds, err := einterfaces.GetElasticSearchInterface().SearchPosts(userChannels, finalParamsList)
+ if err != nil {
+ return nil, err
+ }
+
+ // Get the posts
+ postList := model.NewPostList()
+ if presult := <-Srv.Store.Post().GetPostsByIds(postIds); presult.Err != nil {
+ return nil, presult.Err
} else {
- data := result.Data.(*model.PostList)
- posts.Extend(data)
+ for _, p := range presult.Data.([]*model.Post) {
+ postList.AddPost(p)
+ postList.AddOrder(p.Id)
+ }
}
- }
- return posts, nil
+ return postList, nil
+ } else {
+ channels := []store.StoreChannel{}
+
+ for _, params := range paramsList {
+ params.OrTerms = isOrSearch
+ // don't allow users to search for everything
+ if params.Terms != "*" {
+ channels = append(channels, Srv.Store.Post().Search(teamId, userId, params))
+ }
+ }
+
+ posts := model.NewPostList()
+ for _, channel := range channels {
+ if result := <-channel; result.Err != nil {
+ return nil, result.Err
+ } else {
+ data := result.Data.(*model.PostList)
+ posts.Extend(data)
+ }
+ }
+
+ return posts, nil
+ }
}
func GetFileInfosForPost(postId string, readFromMaster bool) ([]*model.FileInfo, *model.AppError) {