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
 }
 

Reply via email to