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  }