diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 94e4ed8cc4..65f5b5267a 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -23,7 +23,7 @@ import ( const ( issueIndexerAnalyzer = "issueIndexer" issueIndexerDocType = "issueIndexerDocType" - issueIndexerLatestVersion = 6 + issueIndexerLatestVersion = 7 ) const unicodeNormalizeName = "unicodeNormalize" @@ -82,7 +82,7 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) { docMapping.AddFieldMappingsAt("project_id", numberFieldMapping) docMapping.AddFieldMappingsAt("project_board_id", numberFieldMapping) docMapping.AddFieldMappingsAt("poster_id", numberFieldMapping) - docMapping.AddFieldMappingsAt("assignee_id", numberFieldMapping) + docMapping.AddFieldMappingsAt("assignee_ids", numberFieldMapping) docMapping.AddFieldMappingsAt("mention_ids", numberFieldMapping) docMapping.AddFieldMappingsAt("reviewed_ids", numberFieldMapping) docMapping.AddFieldMappingsAt("review_requested_ids", numberFieldMapping) @@ -245,7 +245,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( "project_id": options.ProjectID, "project_board_id": options.ProjectColumnID, "poster_id": options.PosterID, - "assignee_id": options.AssigneeID, + "assignee_ids": options.AssigneeID, "mention_ids": options.MentionID, "reviewed_ids": options.ReviewedID, "review_requested_ids": options.ReviewRequestedID, diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index 4a5e667c14..95efdad6d3 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -18,7 +18,7 @@ import ( ) const ( - issueIndexerLatestVersion = 2 + issueIndexerLatestVersion = 3 // multi-match-types, currently only 2 types are used // Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types esMultiMatchTypeBestFields = "best_fields" @@ -69,7 +69,7 @@ const ( "project_id": { "type": "long", "index": true }, "project_board_id": { "type": "long", "index": true }, "poster_id": { "type": "long", "index": true }, - "assignee_id": { "type": "long", "index": true }, + "assignee_ids": { "type": "long", "index": true }, "mention_ids": { "type": "long", "index": true }, "reviewed_ids": { "type": "long", "index": true }, "review_requested_ids": { "type": "long", "index": true }, @@ -233,7 +233,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( } if options.AssigneeID.Has() { - query.Must(elastic.NewTermQuery("assignee_id", options.AssigneeID.Value())) + query.Must(elastic.NewTermQuery("assignee_ids", options.AssigneeID.Value())) } if options.MentionID.Has() { diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go index 89134dcac7..4034f6d0f9 100644 --- a/modules/indexer/issues/internal/model.go +++ b/modules/indexer/issues/internal/model.go @@ -30,7 +30,7 @@ type IndexerData struct { ProjectID int64 `json:"project_id"` ProjectColumnID int64 `json:"project_board_id"` // the key should be kept as project_board_id to keep compatible PosterID int64 `json:"poster_id"` - AssigneeID int64 `json:"assignee_id"` + AssigneeIDs []int64 `json:"assignee_ids"` MentionIDs []int64 `json:"mention_ids"` ReviewedIDs []int64 `json:"reviewed_ids"` ReviewRequestedIDs []int64 `json:"review_requested_ids"` diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index 4466bf25a7..c4a453c9aa 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -461,10 +461,10 @@ var cases = []*testIndexerCase{ Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) for _, v := range result.Hits { - assert.Equal(t, int64(1), data[v.ID].AssigneeID) + assert.Contains(t, data[v.ID].AssigneeIDs, int64(1)) } assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool { - return v.AssigneeID == 1 + return slices.Contains(v.AssigneeIDs, 1) }), result.Total) }, }, @@ -479,10 +479,10 @@ var cases = []*testIndexerCase{ Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Len(t, result.Hits, 5) for _, v := range result.Hits { - assert.Equal(t, int64(0), data[v.ID].AssigneeID) + assert.Equal(t, []int64{0}, data[v.ID].AssigneeIDs) } assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool { - return v.AssigneeID == 0 + return slices.Contains(v.AssigneeIDs, 0) }), result.Total) }, }, @@ -840,6 +840,14 @@ func generateDefaultIndexerData() []*internal.IndexerData { subscriberIDs[i] = int64(i) + 1 // SubscriberID should not be 0 } + assigneeIDs := make([]int64, 0, 2) + { + if issueIndex%7 == 0 { // If divisible by 7 we insert 1 too to test multiple assignees + assigneeIDs = append(assigneeIDs, 1) + } + assigneeIDs = append(assigneeIDs, issueIndex%10) + } + data = append(data, &internal.IndexerData{ ID: id, Index: issueIndex, @@ -856,7 +864,7 @@ func generateDefaultIndexerData() []*internal.IndexerData { ProjectID: issueIndex % 5, ProjectColumnID: issueIndex % 6, PosterID: id%10 + 1, // PosterID should not be 0 - AssigneeID: issueIndex % 10, + AssigneeIDs: assigneeIDs, MentionIDs: mentionIDs, ReviewedIDs: reviewedIDs, ReviewRequestedIDs: reviewRequestedIDs, diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go index aefe7de517..4ed854dfe6 100644 --- a/modules/indexer/issues/meilisearch/meilisearch.go +++ b/modules/indexer/issues/meilisearch/meilisearch.go @@ -18,7 +18,7 @@ import ( ) const ( - issueIndexerLatestVersion = 3 + issueIndexerLatestVersion = 4 // TODO: make this configurable if necessary maxTotalHits = 10000 @@ -67,7 +67,7 @@ func NewIndexer(url, apiKey, indexerName string) *Indexer { "project_id", "project_board_id", "poster_id", - "assignee_id", + "assignee_ids", "mention_ids", "reviewed_ids", "review_requested_ids", @@ -183,7 +183,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( } if options.AssigneeID.Has() { - query.And(inner_meilisearch.NewFilterEq("assignee_id", options.AssigneeID.Value())) + query.And(inner_meilisearch.NewFilterEq("assignee_ids", options.AssigneeID.Value())) } if options.MentionID.Has() { diff --git a/modules/indexer/issues/util.go b/modules/indexer/issues/util.go index 31b7e888c0..71ee46e235 100644 --- a/modules/indexer/issues/util.go +++ b/modules/indexer/issues/util.go @@ -50,6 +50,15 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD labels = append(labels, label.ID) } + assigneeIDs := make([]int64, 0, len(issue.Assignees)) + if len(issue.Assignees) != 0 { + for _, assignee := range issue.Assignees { + assigneeIDs = append(assigneeIDs, assignee.ID) + } + } else { + assigneeIDs = append(assigneeIDs, 0) + } + mentionIDs, err := issues_model.GetIssueMentionIDs(ctx, issueID) if err != nil { return nil, false, err @@ -108,7 +117,7 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD ProjectID: projectID, ProjectColumnID: issue.ProjectColumnID(ctx), PosterID: issue.PosterID, - AssigneeID: issue.AssigneeID, + AssigneeIDs: assigneeIDs, MentionIDs: mentionIDs, ReviewedIDs: reviewedIDs, ReviewRequestedIDs: reviewRequestedIDs,