Added from:, in:, and channel: search modifiers
Этот коммит содержится в:
@@ -407,15 +407,23 @@ var specialSearchChar = []string{
|
||||
"@",
|
||||
}
|
||||
|
||||
func (s SqlPostStore) Search(teamId string, userId string, terms string, isHashtagSearch bool) StoreChannel {
|
||||
func (s SqlPostStore) Search(teamId string, userId string, params *model.SearchParams) StoreChannel {
|
||||
storeChannel := make(StoreChannel)
|
||||
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
termMap := map[string]bool{}
|
||||
terms := params.Terms
|
||||
|
||||
if terms == "" && params.InChannel == "" && params.FromUser == "" {
|
||||
result.Data = []*model.Post{}
|
||||
storeChannel <- result
|
||||
return
|
||||
}
|
||||
|
||||
searchType := "Message"
|
||||
if isHashtagSearch {
|
||||
if params.IsHashtag {
|
||||
searchType = "Hashtags"
|
||||
for _, term := range strings.Split(terms, " ") {
|
||||
termMap[term] = true
|
||||
@@ -430,63 +438,85 @@ func (s SqlPostStore) Search(teamId string, userId string, terms string, isHasht
|
||||
var posts []*model.Post
|
||||
|
||||
if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
|
||||
// Parse text for wildcards
|
||||
if wildcard, err := regexp.Compile("\\*($| )"); err == nil {
|
||||
terms = wildcard.ReplaceAllLiteralString(terms, ":* ")
|
||||
}
|
||||
}
|
||||
|
||||
searchQuery := `
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
Posts
|
||||
WHERE
|
||||
DeleteAt = 0
|
||||
POST_FILTER
|
||||
AND ChannelId IN (
|
||||
SELECT
|
||||
Id
|
||||
FROM
|
||||
Channels,
|
||||
ChannelMembers
|
||||
WHERE
|
||||
Id = ChannelId
|
||||
AND TeamId = :TeamId
|
||||
AND UserId = :UserId
|
||||
AND DeleteAt = 0
|
||||
CHANNEL_FILTER)
|
||||
SEARCH_CLAUSE
|
||||
ORDER BY CreateAt DESC
|
||||
LIMIT 100`
|
||||
|
||||
if params.InChannel != "" {
|
||||
searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "AND Name = :InChannel", 1)
|
||||
} else {
|
||||
searchQuery = strings.Replace(searchQuery, "CHANNEL_FILTER", "", 1)
|
||||
}
|
||||
|
||||
if params.FromUser != "" {
|
||||
searchQuery = strings.Replace(searchQuery, "POST_FILTER", `
|
||||
AND UserId IN (
|
||||
SELECT
|
||||
Id
|
||||
FROM
|
||||
Users
|
||||
WHERE
|
||||
TeamId = :TeamId
|
||||
AND Username = :FromUser)`, 1)
|
||||
} else {
|
||||
searchQuery = strings.Replace(searchQuery, "POST_FILTER", "", 1)
|
||||
}
|
||||
|
||||
if terms == "" {
|
||||
// we've already confirmed that we have a channel or user to search for
|
||||
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", "", 1)
|
||||
} else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_POSTGRES {
|
||||
// Parse text for wildcards
|
||||
if wildcard, err := regexp.Compile("\\*($| )"); err == nil {
|
||||
terms = wildcard.ReplaceAllLiteralString(terms, ":* ")
|
||||
}
|
||||
|
||||
searchQuery := fmt.Sprintf(`SELECT
|
||||
*
|
||||
FROM
|
||||
Posts
|
||||
WHERE
|
||||
DeleteAt = 0
|
||||
AND ChannelId IN (SELECT
|
||||
Id
|
||||
FROM
|
||||
Channels,
|
||||
ChannelMembers
|
||||
WHERE
|
||||
Id = ChannelId AND TeamId = $1
|
||||
AND UserId = $2
|
||||
AND DeleteAt = 0)
|
||||
AND %s @@ to_tsquery($3)
|
||||
ORDER BY CreateAt DESC
|
||||
LIMIT 100`, searchType)
|
||||
|
||||
terms = strings.Join(strings.Fields(terms), " | ")
|
||||
|
||||
_, err := s.GetReplica().Select(&posts, searchQuery, teamId, userId, terms)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
|
||||
|
||||
}
|
||||
searchClause := fmt.Sprintf("AND %s @@ to_tsquery(:Terms)", searchType)
|
||||
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1)
|
||||
} else if utils.Cfg.SqlSettings.DriverName == model.DATABASE_DRIVER_MYSQL {
|
||||
searchQuery := fmt.Sprintf(`SELECT
|
||||
*
|
||||
FROM
|
||||
Posts
|
||||
WHERE
|
||||
DeleteAt = 0
|
||||
AND ChannelId IN (SELECT
|
||||
Id
|
||||
FROM
|
||||
Channels,
|
||||
ChannelMembers
|
||||
WHERE
|
||||
Id = ChannelId AND TeamId = ?
|
||||
AND UserId = ?
|
||||
AND DeleteAt = 0)
|
||||
AND MATCH (%s) AGAINST (? IN BOOLEAN MODE)
|
||||
ORDER BY CreateAt DESC
|
||||
LIMIT 100`, searchType)
|
||||
searchClause := fmt.Sprintf("AND MATCH (%s) AGAINST (:Terms IN BOOLEAN MODE)", searchType)
|
||||
searchQuery = strings.Replace(searchQuery, "SEARCH_CLAUSE", searchClause, 1)
|
||||
}
|
||||
|
||||
_, err := s.GetReplica().Select(&posts, searchQuery, teamId, userId, terms)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
|
||||
queryParams := map[string]interface{}{
|
||||
"TeamId": teamId,
|
||||
"UserId": userId,
|
||||
"Terms": terms,
|
||||
"InChannel": params.InChannel,
|
||||
"FromUser": params.FromUser,
|
||||
}
|
||||
|
||||
}
|
||||
_, err := s.GetReplica().Select(&posts, searchQuery, queryParams)
|
||||
if err != nil {
|
||||
result.Err = model.NewAppError("SqlPostStore.Search", "We encounted an error while searching for posts", "teamId="+teamId+", err="+err.Error())
|
||||
}
|
||||
|
||||
list := &model.PostList{Order: make([]string, 0, len(posts))}
|
||||
|
||||
@@ -525,57 +525,57 @@ func TestPostStoreSearch(t *testing.T) {
|
||||
o5.Hashtags = "#secret #howdy"
|
||||
o5 = (<-store.Post().Save(o5)).Data.(*model.Post)
|
||||
|
||||
r1 := (<-store.Post().Search(teamId, userId, "corey", false)).Data.(*model.PostList)
|
||||
r1 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "corey", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r1.Order) != 1 && r1.Order[0] != o1.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r3 := (<-store.Post().Search(teamId, userId, "new", false)).Data.(*model.PostList)
|
||||
r3 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "new", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r3.Order) != 2 && r3.Order[0] != o1.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r4 := (<-store.Post().Search(teamId, userId, "john", false)).Data.(*model.PostList)
|
||||
r4 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "john", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r4.Order) != 1 && r4.Order[0] != o2.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r5 := (<-store.Post().Search(teamId, userId, "matter*", false)).Data.(*model.PostList)
|
||||
r5 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter*", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r5.Order) != 1 && r5.Order[0] != o1.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r6 := (<-store.Post().Search(teamId, userId, "#hashtag", true)).Data.(*model.PostList)
|
||||
r6 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "#hashtag", IsHashtag: true})).Data.(*model.PostList)
|
||||
if len(r6.Order) != 1 && r6.Order[0] != o4.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r7 := (<-store.Post().Search(teamId, userId, "#secret", true)).Data.(*model.PostList)
|
||||
r7 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "#secret", IsHashtag: true})).Data.(*model.PostList)
|
||||
if len(r7.Order) != 1 && r7.Order[0] != o5.Id {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r8 := (<-store.Post().Search(teamId, userId, "@thisshouldmatchnothing", true)).Data.(*model.PostList)
|
||||
r8 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "@thisshouldmatchnothing", IsHashtag: true})).Data.(*model.PostList)
|
||||
if len(r8.Order) != 0 {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r9 := (<-store.Post().Search(teamId, userId, "mattermost jersey", false)).Data.(*model.PostList)
|
||||
r9 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "mattermost jersey", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r9.Order) != 2 {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r10 := (<-store.Post().Search(teamId, userId, "matter* jer*", false)).Data.(*model.PostList)
|
||||
r10 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "matter* jer*", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r10.Order) != 2 {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r11 := (<-store.Post().Search(teamId, userId, "message blargh", false)).Data.(*model.PostList)
|
||||
r11 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "message blargh", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r11.Order) != 1 {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
r12 := (<-store.Post().Search(teamId, userId, "blargh>", false)).Data.(*model.PostList)
|
||||
r12 := (<-store.Post().Search(teamId, userId, &model.SearchParams{Terms: "blargh>", IsHashtag: false})).Data.(*model.PostList)
|
||||
if len(r12.Order) != 1 {
|
||||
t.Fatal("returned wrong search result")
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ type PostStore interface {
|
||||
GetPosts(channelId string, offset int, limit int) StoreChannel
|
||||
GetPostsSince(channelId string, time int64) StoreChannel
|
||||
GetEtag(channelId string) StoreChannel
|
||||
Search(teamId string, userId string, terms string, isHashtagSearch bool) StoreChannel
|
||||
Search(teamId string, userId string, params *model.SearchParams) StoreChannel
|
||||
GetForExport(channelId string) StoreChannel
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user