This is an automated email from the ASF dual-hosted git repository.
linkinstar pushed a commit to branch feat/1.4.2/tag
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
The following commit(s) were added to refs/heads/feat/1.4.2/tag by this push:
new 5cbd1906 feat(question): add linked count feature to question
5cbd1906 is described below
commit 5cbd1906ae159421388ffefcbe24d4cdab8af7c3
Author: LinkinStars <[email protected]>
AuthorDate: Tue Nov 19 18:01:38 2024 +0800
feat(question): add linked count feature to question
---
internal/entity/question_entity.go | 1 +
internal/migrations/migrations.go | 1 +
internal/migrations/v24.go | 34 +++++++++++++++++++++++
internal/repo/question/question_repo.go | 40 ++++++++++++++++++++++++++++
internal/schema/question_schema.go | 4 +--
internal/service/question_common/question.go | 23 ++++++++++++++++
6 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/internal/entity/question_entity.go
b/internal/entity/question_entity.go
index 1931282c..9e5dcd11 100644
--- a/internal/entity/question_entity.go
+++ b/internal/entity/question_entity.go
@@ -73,6 +73,7 @@ type Question struct {
LastAnswerID string `xorm:"not null default 0 BIGINT(20)
last_answer_id"`
PostUpdateTime time.Time `xorm:"post_update_time TIMESTAMP"`
RevisionID string `xorm:"not null default 0 BIGINT(20)
revision_id"`
+ LinkedCount int `xorm:"not null default 0 INT(11)
linked_count"`
}
// TableName question table name
diff --git a/internal/migrations/migrations.go
b/internal/migrations/migrations.go
index 81a54ae7..00e44198 100644
--- a/internal/migrations/migrations.go
+++ b/internal/migrations/migrations.go
@@ -99,6 +99,7 @@ var migrations = []Migration{
NewMigration("v1.3.6", "add hot score to question table",
addQuestionHotScore, true),
NewMigration("v1.4.0", "add badge/badge_group/badge_award table",
addBadges, true),
NewMigration("v1.4.1", "add question link", addQuestionLink, true),
+ NewMigration("v1.4.2", "add the number of question links",
addQuestionLinkedCount, false),
}
func GetMigrations() []Migration {
diff --git a/internal/migrations/v24.go b/internal/migrations/v24.go
new file mode 100644
index 00000000..015352ae
--- /dev/null
+++ b/internal/migrations/v24.go
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package migrations
+
+import (
+ "context"
+ "github.com/apache/incubator-answer/internal/entity"
+
+ "xorm.io/xorm"
+)
+
+func addQuestionLinkedCount(ctx context.Context, x *xorm.Engine) error {
+ type Question struct {
+ LinkedCount int `xorm:"not null default 0 INT(11) linked_count"`
+ }
+ return x.Context(ctx).Sync(new(entity.Question))
+}
diff --git a/internal/repo/question/question_repo.go
b/internal/repo/question/question_repo.go
index 1132501e..e1d94f2e 100644
--- a/internal/repo/question/question_repo.go
+++ b/internal/repo/question/question_repo.go
@@ -410,6 +410,8 @@ func (qr *questionRepo) GetQuestionPage(ctx
context.Context, page, pageSize int,
case "unanswered":
session.Where("question.answer_count = 0")
session.OrderBy("question.pin desc,question.created_at DESC")
+ case "frequent":
+ session.OrderBy("question.pin DESC, question.linked_count DESC")
}
total, err = pager.Help(page, pageSize, &questionList,
&entity.Question{}, session)
@@ -708,6 +710,42 @@ func (qr *questionRepo) LinkQuestion(ctx context.Context,
link ...*entity.Questi
return
}
+// UpdateQuestionLinkCount update question link count
+func (qr *questionRepo) UpdateQuestionLinkCount(ctx context.Context,
questionID string) (err error) {
+ // count the number of links
+ count, err := qr.data.DB.Context(ctx).
+ Where("to_question_id = ?", questionID).
+ Where("status = ?", entity.QuestionLinkStatusAvailable).
+ Count(&entity.QuestionLink{})
+ if err != nil {
+ return
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ }
+
+ // update the number of links
+ _, err = qr.data.DB.Context(ctx).ID(questionID).
+ Cols("linked_count").Update(&entity.Question{LinkedCount:
int(count)})
+ if err != nil {
+ return
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ }
+ return
+}
+
+// GetLinkedQuestionIDs get linked question ids
+func (qr *questionRepo) GetLinkedQuestionIDs(ctx context.Context, questionID
string, status int) (
+ questionIDs []string, err error) {
+ questionIDs = make([]string, 0)
+ err = qr.data.DB.Context(ctx).
+ Select("to_question_id").
+ Table(new(entity.QuestionLink).TableName()).
+ Where("from_question_id = ?", questionID).
+ Where("status = ?", status).
+ Find(&questionIDs)
+ if err != nil {
+ return nil,
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ }
+ return questionIDs, nil
+}
+
// RecoverQuestionLink batch recover question link
func (qr *questionRepo) RecoverQuestionLink(ctx context.Context, links
...*entity.QuestionLink) (err error) {
return qr.UpdateQuestionLinkStatus(ctx,
entity.QuestionLinkStatusAvailable, links...)
@@ -784,6 +822,8 @@ func (qr *questionRepo) GetQuestionLink(ctx
context.Context, page, pageSize int,
case "unanswered":
session.Where("question.answer_count = 0")
session.OrderBy("question.pin desc,question.created_at DESC")
+ case "frequent":
+ session.OrderBy("question.pin DESC, question.linked_count DESC")
}
if page > 0 && pageSize > 0 {
diff --git a/internal/schema/question_schema.go
b/internal/schema/question_schema.go
index de19a8a5..accc3374 100644
--- a/internal/schema/question_schema.go
+++ b/internal/schema/question_schema.go
@@ -356,7 +356,7 @@ const (
type QuestionPageReq struct {
Page int `validate:"omitempty,min=1" form:"page"`
PageSize int `validate:"omitempty,min=1" form:"page_size"`
- OrderCond string `validate:"omitempty,oneof=newest active hot score
unanswered recommend" form:"order"`
+ OrderCond string `validate:"omitempty,oneof=newest active hot score
unanswered recommend frequent" form:"order"`
Tag string `validate:"omitempty,gt=0,lte=100" form:"tag"`
Username string `validate:"omitempty,gt=0,lte=100" form:"username"`
InDays int `validate:"omitempty,min=1" form:"in_days"`
@@ -504,7 +504,7 @@ type GetQuestionLinkReq struct {
Page int `validate:"omitempty,min=1" form:"page"`
PageSize int `validate:"omitempty,min=1,max=100" form:"page_size"`
QuestionID string `validate:"required" form:"question_id"`
- OrderCond string `validate:"omitempty,oneof=newest active hot score
unanswered recommend" form:"order"`
+ OrderCond string `validate:"omitempty,oneof=newest active hot score
unanswered recommend frequent" form:"order"`
InDays int `validate:"omitempty,min=1" form:"in_days"`
LoginUserID string `json:"-"`
diff --git a/internal/service/question_common/question.go
b/internal/service/question_common/question.go
index 08c74f29..fc01159e 100644
--- a/internal/service/question_common/question.go
+++ b/internal/service/question_common/question.go
@@ -81,6 +81,8 @@ type QuestionRepo interface {
RemoveAllUserQuestion(ctx context.Context, userID string) (err error)
UpdateSearch(ctx context.Context, questionID string) (err error)
LinkQuestion(ctx context.Context, link ...*entity.QuestionLink) (err
error)
+ GetLinkedQuestionIDs(ctx context.Context, questionID string, status
int) (questionIDs []string, err error)
+ UpdateQuestionLinkCount(ctx context.Context, questionID string) (err
error)
RemoveQuestionLink(ctx context.Context, link ...*entity.QuestionLink)
(err error)
RecoverQuestionLink(ctx context.Context, link ...*entity.QuestionLink)
(err error)
UpdateQuestionLinkStatus(ctx context.Context, status int, links
...*entity.QuestionLink) (err error)
@@ -704,6 +706,17 @@ func (qs *QuestionCommon) UpdateQuestionLink(ctx
context.Context, questionID, an
if err != nil {
return parsedText, err
}
+ // Update the number of question links that have been removed
+ linkedQuestionIDs, err := qs.questionRepo.GetLinkedQuestionIDs(ctx,
questionID, entity.QuestionLinkStatusDeleted)
+ if err != nil {
+ log.Errorf("get linked question ids error %v", err)
+ } else {
+ for _, id := range linkedQuestionIDs {
+ if err := qs.questionRepo.UpdateQuestionLinkCount(ctx,
id); err != nil {
+ log.Errorf("update question link count error
%v", err)
+ }
+ }
+ }
links := checker.GetQuestionLink(originalText)
if len(links) == 0 {
@@ -799,6 +812,16 @@ func (qs *QuestionCommon) UpdateQuestionLink(ctx
context.Context, questionID, an
}
}
+ // update question linked count
+ for _, link := range validLinks {
+ if len(link.ToQuestionID) == 0 {
+ continue
+ }
+ if err := qs.questionRepo.UpdateQuestionLinkCount(ctx,
link.ToQuestionID); err != nil {
+ log.Errorf("update question link count error %v", err)
+ }
+ }
+
return parsedText, nil
}