github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/store/searchlayer/post_layer.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package searchlayer 5 6 import ( 7 "context" 8 9 "github.com/masterhung0112/hk_server/v5/model" 10 "github.com/masterhung0112/hk_server/v5/services/searchengine" 11 "github.com/masterhung0112/hk_server/v5/shared/mlog" 12 "github.com/masterhung0112/hk_server/v5/store" 13 "github.com/pkg/errors" 14 ) 15 16 type SearchPostStore struct { 17 store.PostStore 18 rootStore *SearchStore 19 } 20 21 func (s SearchPostStore) indexPost(post *model.Post) { 22 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 23 if engine.IsIndexingEnabled() { 24 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 25 channel, chanErr := s.rootStore.Channel().Get(post.ChannelId, true) 26 if chanErr != nil { 27 mlog.Error("Couldn't get channel for post for SearchEngine indexing.", mlog.String("channel_id", post.ChannelId), mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id), mlog.Err(chanErr)) 28 return 29 } 30 if err := engineCopy.IndexPost(post, channel.TeamId); err != nil { 31 mlog.Warn("Encountered error indexing post", mlog.String("post_id", post.Id), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 32 return 33 } 34 mlog.Debug("Indexed post in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id)) 35 }) 36 } 37 } 38 } 39 40 func (s SearchPostStore) deletePostIndex(post *model.Post) { 41 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 42 if engine.IsIndexingEnabled() { 43 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 44 if err := engineCopy.DeletePost(post); err != nil { 45 mlog.Warn("Encountered error deleting post", mlog.String("post_id", post.Id), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 46 return 47 } 48 mlog.Debug("Removed post from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id)) 49 }) 50 } 51 } 52 } 53 54 func (s SearchPostStore) deleteChannelPostsIndex(channelID string) { 55 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 56 if engine.IsIndexingEnabled() { 57 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 58 if err := engineCopy.DeleteChannelPosts(channelID); err != nil { 59 mlog.Warn("Encountered error deleting channel posts", mlog.String("channel_id", channelID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 60 return 61 } 62 mlog.Debug("Removed all channel posts from the index in search engine", mlog.String("channel_id", channelID), mlog.String("search_engine", engineCopy.GetName())) 63 }) 64 } 65 } 66 } 67 68 func (s SearchPostStore) deleteUserPostsIndex(userID string) { 69 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 70 if engine.IsIndexingEnabled() { 71 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 72 if err := engineCopy.DeleteUserPosts(userID); err != nil { 73 mlog.Warn("Encountered error deleting user posts", mlog.String("user_id", userID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 74 return 75 } 76 mlog.Debug("Removed all user posts from the index in search engine", mlog.String("user_id", userID), mlog.String("search_engine", engineCopy.GetName())) 77 }) 78 } 79 } 80 } 81 82 func (s SearchPostStore) Update(newPost, oldPost *model.Post) (*model.Post, error) { 83 post, err := s.PostStore.Update(newPost, oldPost) 84 85 if err == nil { 86 s.indexPost(post) 87 } 88 return post, err 89 } 90 91 func (s *SearchPostStore) Overwrite(post *model.Post) (*model.Post, error) { 92 post, err := s.PostStore.Overwrite(post) 93 if err == nil { 94 s.indexPost(post) 95 } 96 return post, err 97 } 98 99 func (s SearchPostStore) Save(post *model.Post) (*model.Post, error) { 100 npost, err := s.PostStore.Save(post) 101 102 if err == nil { 103 s.indexPost(npost) 104 } 105 return npost, err 106 } 107 108 func (s SearchPostStore) Delete(postId string, date int64, deletedByID string) error { 109 err := s.PostStore.Delete(postId, date, deletedByID) 110 111 if err == nil { 112 postList, err2 := s.PostStore.Get(context.Background(), postId, true, false, false, "") 113 if postList != nil && len(postList.Order) > 0 { 114 if err2 != nil { 115 s.deletePostIndex(postList.Posts[postList.Order[0]]) 116 } 117 } 118 } 119 return err 120 } 121 122 func (s SearchPostStore) PermanentDeleteByUser(userID string) error { 123 err := s.PostStore.PermanentDeleteByUser(userID) 124 if err == nil { 125 s.deleteUserPostsIndex(userID) 126 } 127 return err 128 } 129 130 func (s SearchPostStore) PermanentDeleteByChannel(channelID string) error { 131 err := s.PostStore.PermanentDeleteByChannel(channelID) 132 if err == nil { 133 s.deleteChannelPostsIndex(channelID) 134 } 135 return err 136 } 137 138 func (s SearchPostStore) searchPostsInTeamForUserByEngine(engine searchengine.SearchEngineInterface, paramsList []*model.SearchParams, userId, teamId string, page, perPage int) (*model.PostSearchResults, error) { 139 if err := model.IsSearchParamsListValid(paramsList); err != nil { 140 return nil, err 141 } 142 143 // We only allow the user to search in channels they are a member of. 144 userChannels, err2 := s.rootStore.Channel().GetChannels(teamId, userId, paramsList[0].IncludeDeletedChannels, 0) 145 if err2 != nil { 146 return nil, errors.Wrap(err2, "error getting channel for user") 147 } 148 149 postIds, matches, err := engine.SearchPosts(userChannels, paramsList, page, perPage) 150 if err != nil { 151 return nil, err 152 } 153 154 // Get the posts 155 postList := model.NewPostList() 156 if len(postIds) > 0 { 157 posts, err := s.PostStore.GetPostsByIds(postIds) 158 if err != nil { 159 return nil, err 160 } 161 for _, p := range posts { 162 if p.DeleteAt == 0 { 163 postList.AddPost(p) 164 postList.AddOrder(p.Id) 165 } 166 } 167 } 168 169 return model.MakePostSearchResults(postList, matches), nil 170 } 171 172 func (s SearchPostStore) SearchPostsInTeamForUser(paramsList []*model.SearchParams, userId, teamId string, page, perPage int) (*model.PostSearchResults, error) { 173 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 174 if engine.IsSearchEnabled() { 175 results, err := s.searchPostsInTeamForUserByEngine(engine, paramsList, userId, teamId, page, perPage) 176 if err != nil { 177 mlog.Warn("Encountered error on SearchPostsInTeamForUser.", mlog.String("search_engine", engine.GetName()), mlog.Err(err)) 178 continue 179 } 180 mlog.Debug("Using the first available search engine", mlog.String("search_engine", engine.GetName())) 181 return results, err 182 } 183 } 184 185 if *s.rootStore.getConfig().SqlSettings.DisableDatabaseSearch { 186 mlog.Debug("Returning empty results for post SearchPostsInTeam as the database search is disabled") 187 return &model.PostSearchResults{PostList: model.NewPostList(), Matches: model.PostSearchMatches{}}, nil 188 } 189 190 mlog.Debug("Using database search because no other search engine is available") 191 return s.PostStore.SearchPostsInTeamForUser(paramsList, userId, teamId, page, perPage) 192 }