Browse Source

增加数据集的私有搜索

Signed-off-by: zouap <zouap@pcl.ac.cn>
tags/v1.22.3.2^2
zouap 3 years ago
parent
commit
e194cfe9c4
5 changed files with 162 additions and 27 deletions
  1. +11
    -3
      models/dbsql/dataset_foreigntable_for_es.sql
  2. +6
    -4
      models/dbsql/repo_foreigntable_for_es.sql
  3. +21
    -9
      models/dbsql/user_foreigntable_for_es.sql
  4. +29
    -3
      models/search_record.go
  5. +95
    -8
      routers/search.go

+ 11
- 3
models/dbsql/dataset_foreigntable_for_es.sql View File

@@ -55,6 +55,9 @@ DELETE FROM public.dataset_es;
b.updated_unix,(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false) b.updated_unix,(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false)
FROM public.dataset b,public.repository c where b.repo_id=c.id and c.is_private=false; FROM public.dataset b,public.repository c where b.repo_id=c.id and c.is_private=false;



DROP TRIGGER IF EXISTS es_insert_dataset on public.dataset;

CREATE OR REPLACE FUNCTION public.insert_dataset_data() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.insert_dataset_data() RETURNS trigger AS
$def$ $def$
DECLARE DECLARE
@@ -97,7 +100,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_insert_dataset on public.dataset;


CREATE TRIGGER es_insert_dataset CREATE TRIGGER es_insert_dataset
AFTER INSERT ON public.dataset AFTER INSERT ON public.dataset
@@ -105,6 +108,9 @@ CREATE TRIGGER es_insert_dataset


ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_insert_dataset; ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_insert_dataset;



DROP TRIGGER IF EXISTS es_udpate_dataset_file_name_delete on public.attachment;

CREATE OR REPLACE FUNCTION public.udpate_dataset_file_name_delete() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.udpate_dataset_file_name_delete() RETURNS trigger AS
$def$ $def$
BEGIN BEGIN
@@ -114,7 +120,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_udpate_dataset_file_name_delete on public.attachment;
CREATE TRIGGER es_udpate_dataset_file_name_delete CREATE TRIGGER es_udpate_dataset_file_name_delete
AFTER DELETE ON public.attachment AFTER DELETE ON public.attachment
FOR EACH ROW EXECUTE PROCEDURE udpate_dataset_file_name_delete(); FOR EACH ROW EXECUTE PROCEDURE udpate_dataset_file_name_delete();
@@ -145,6 +151,8 @@ CREATE TRIGGER es_update_dataset


ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_update_dataset; ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_update_dataset;


DROP TRIGGER IF EXISTS es_delete_dataset on public.dataset;

CREATE OR REPLACE FUNCTION public.delete_dataset() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.delete_dataset() RETURNS trigger AS
$def$ $def$
declare declare
@@ -155,7 +163,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_delete_dataset on public.dataset;
CREATE TRIGGER es_delete_dataset CREATE TRIGGER es_delete_dataset
AFTER DELETE ON public.dataset AFTER DELETE ON public.dataset
FOR EACH ROW EXECUTE PROCEDURE delete_dataset(); FOR EACH ROW EXECUTE PROCEDURE delete_dataset();


+ 6
- 4
models/dbsql/repo_foreigntable_for_es.sql View File

@@ -156,6 +156,7 @@ delete from public.repository_es;
lower_alias lower_alias
FROM public.repository b where b.is_private=false; FROM public.repository b where b.is_private=false;


DROP TRIGGER IF EXISTS es_insert_repository on public.repository;


CREATE OR REPLACE FUNCTION public.insert_repository_data() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.insert_repository_data() RETURNS trigger AS
$def$ $def$
@@ -257,8 +258,6 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_insert_repository on public.repository;



CREATE TRIGGER es_insert_repository CREATE TRIGGER es_insert_repository
AFTER INSERT ON public.repository AFTER INSERT ON public.repository
@@ -483,6 +482,9 @@ CREATE TRIGGER es_update_repository


ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_update_repository; ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_update_repository;



DROP TRIGGER IF EXISTS es_delete_repository on public.repository;

CREATE OR REPLACE FUNCTION public.delete_repository() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.delete_repository() RETURNS trigger AS
$def$ $def$
declare declare
@@ -495,7 +497,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_delete_repository on public.repository;
CREATE TRIGGER es_delete_repository CREATE TRIGGER es_delete_repository
AFTER DELETE ON public.repository AFTER DELETE ON public.repository
FOR EACH ROW EXECUTE PROCEDURE delete_repository(); FOR EACH ROW EXECUTE PROCEDURE delete_repository();
@@ -514,7 +516,7 @@ $def$
elsif (TG_OP = 'INSERT') then elsif (TG_OP = 'INSERT') then
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id;
elsif (TG_OP = 'DELETE') then elsif (TG_OP = 'DELETE') then
if exists(select 1 from public.repository where id=OLD.repo_id)
if exists(select 1 from public.repository where id=OLD.repo_id) then
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id; update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id;
end if; end if;
end if; end if;


+ 21
- 9
models/dbsql/user_foreigntable_for_es.sql View File

@@ -49,7 +49,8 @@ CREATE FOREIGN TABLE public.user_es
token character varying(1024) , token character varying(1024) ,
public_key character varying(255), public_key character varying(255),
private_key character varying(255), private_key character varying(255),
is_operator boolean NOT NULL DEFAULT false
is_operator boolean NOT NULL DEFAULT false,
num_dataset_stars integer NOT NULL DEFAULT 0
) SERVER multicorn_es ) SERVER multicorn_es
OPTIONS OPTIONS
( (
@@ -103,7 +104,8 @@ delete from public.user_es;
repo_admin_change_team_access, repo_admin_change_team_access,
diff_view_style, diff_view_style,
theme, theme,
is_operator)
is_operator,
num_dataset_stars)
SELECT SELECT
id, id,
lower_name, lower_name,
@@ -146,9 +148,12 @@ delete from public.user_es;
repo_admin_change_team_access, repo_admin_change_team_access,
diff_view_style, diff_view_style,
theme, theme,
is_operator
is_operator,
num_dataset_stars
FROM public.user; FROM public.user;


DROP TRIGGER IF EXISTS es_insert_user on public.user;

CREATE OR REPLACE FUNCTION public.insert_user_data() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.insert_user_data() RETURNS trigger AS
$def$ $def$
BEGIN BEGIN
@@ -194,7 +199,8 @@ $def$
repo_admin_change_team_access, repo_admin_change_team_access,
diff_view_style, diff_view_style,
theme, theme,
is_operator)
is_operator,
num_dataset_stars)
VALUES ( VALUES (
NEW.id, NEW.id,
NEW.lower_name, NEW.lower_name,
@@ -237,7 +243,8 @@ $def$
NEW.repo_admin_change_team_access, NEW.repo_admin_change_team_access,
NEW.diff_view_style, NEW.diff_view_style,
NEW.theme, NEW.theme,
NEW.is_operator
NEW.is_operator,
NEW.num_dataset_stars
); );


RETURN NEW; RETURN NEW;
@@ -245,7 +252,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_insert_user on public.user;


CREATE TRIGGER es_insert_user CREATE TRIGGER es_insert_user
AFTER INSERT ON public.user AFTER INSERT ON public.user
@@ -253,6 +260,7 @@ CREATE TRIGGER es_insert_user


ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_insert_user; ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_insert_user;


DROP TRIGGER IF EXISTS es_update_user on public.user;


CREATE OR REPLACE FUNCTION public.update_user() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.update_user() RETURNS trigger AS
$def$ $def$
@@ -263,14 +271,16 @@ $def$
full_name=NEW.full_name, full_name=NEW.full_name,
location=NEW.location, location=NEW.location,
website=NEW.website, website=NEW.website,
email=NEW.email
email=NEW.email,
num_dataset_stars=NEW.num_dataset_stars,
updated_unix=NEW.updated_unix
where id=NEW.id; where id=NEW.id;
return new; return new;
END END
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_update_user on public.user;


CREATE TRIGGER es_update_user CREATE TRIGGER es_update_user
AFTER UPDATE ON public.user AFTER UPDATE ON public.user
@@ -278,6 +288,8 @@ CREATE TRIGGER es_update_user


ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_update_user; ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_update_user;


DROP TRIGGER IF EXISTS es_delete_user on public.user;

CREATE OR REPLACE FUNCTION public.delete_user() RETURNS trigger AS CREATE OR REPLACE FUNCTION public.delete_user() RETURNS trigger AS
$def$ $def$
declare declare
@@ -288,7 +300,7 @@ $def$
$def$ $def$
LANGUAGE plpgsql; LANGUAGE plpgsql;


DROP TRIGGER IF EXISTS es_delete_user on public.user;
CREATE TRIGGER es_delete_user CREATE TRIGGER es_delete_user
AFTER DELETE ON public.user AFTER DELETE ON public.user
FOR EACH ROW EXECUTE PROCEDURE delete_user(); FOR EACH ROW EXECUTE PROCEDURE delete_user();


+ 29
- 3
models/search_record.go View File

@@ -28,7 +28,7 @@ func SaveSearchKeywordToDb(keyword string) error {
return nil return nil
} }


func setQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId int64) {
func setIssueQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId int64) {
sess.And("issue.poster_id=?", userId) sess.And("issue.poster_id=?", userId)
sess.And("issue.is_pull=?", isPull) sess.And("issue.is_pull=?", isPull)
sess.And("(issue.name like '%" + Keyword + "%' or issue.content like '%" + Keyword + "%')") sess.And("(issue.name like '%" + Keyword + "%' or issue.content like '%" + Keyword + "%')")
@@ -38,13 +38,13 @@ func setQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId i
func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool, userId int64) ([]*Issue, int64, error) { func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool, userId int64) ([]*Issue, int64, error) {
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()
setQueryCondition(sess, Keyword, isPull, userId)
setIssueQueryCondition(sess, Keyword, isPull, userId)
count, err := sess.Count(new(Issue)) count, err := sess.Count(new(Issue))
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }


setQueryCondition(sess, Keyword, isPull, userId)
setIssueQueryCondition(sess, Keyword, isPull, userId)
sess.Desc("issue.created_unix") sess.Desc("issue.created_unix")
sess.Limit(PageSize, (Page-1)*PageSize) sess.Limit(PageSize, (Page-1)*PageSize)
issues := make([]*Issue, 0) issues := make([]*Issue, 0)
@@ -53,5 +53,31 @@ func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool,
} else { } else {
return issues, count, nil return issues, count, nil
} }
}

func setDataSetQueryCondition(sess *xorm.Session, Keyword string, userId int64) {
sess.And("dataset.user_id=?", userId)
sess.And("(dataset.title like '%" + Keyword + "%' or dataset.description like '%" + Keyword + "%')")
sess.Join("INNER", "repository", "dataset.repo_id = repository.id").And("repository.is_private = ?", true)
}

func SearchDatasetBySQL(Page int, PageSize int, Keyword string, userId int64) ([]*Dataset, int64, error) {
sess := x.NewSession()
defer sess.Close()
setDataSetQueryCondition(sess, Keyword, userId)
count, err := sess.Count(new(Dataset))
if err != nil {
return nil, 0, err
}

setDataSetQueryCondition(sess, Keyword, userId)
sess.Desc("issue.created_unix")
sess.Limit(PageSize, (Page-1)*PageSize)
datasets := make([]*Dataset, 0)
if err := sess.Find(&datasets); err != nil {
return nil, 0, err
} else {
return datasets, count, nil
}


} }

+ 95
- 8
routers/search.go View File

@@ -770,9 +770,54 @@ func searchDataSet(ctx *context.Context, TableName string, Key string, Page int,
download_times download_times


*/ */
log.Info("query searchdataset start")
SortBy := ctx.Query("SortBy") SortBy := ctx.Query("SortBy")
ascending := ctx.QueryBool("Ascending") ascending := ctx.QueryBool("Ascending")
log.Info("query searchRepo start")
PrivateTotal := ctx.QueryInt("PrivateTotal")
WebTotal := ctx.QueryInt("WebTotal")

from := (Page - 1) * PageSize
if from == 0 {
WebTotal = 0
}
resultObj := &SearchRes{}
log.Info("WebTotal=" + fmt.Sprint(WebTotal))
log.Info("PrivateTotal=" + fmt.Sprint(PrivateTotal))
resultObj.Result = make([]map[string]interface{}, 0)

if ctx.User != nil && (from < PrivateTotal || from == 0) {

log.Info("actor is null?:" + fmt.Sprint(ctx.User == nil))
datasets, count, err := models.SearchDatasetBySQL(Page, PageSize, Key, ctx.User.ID)
if err != nil {
ctx.JSON(200, "")
return
}
resultObj.PrivateTotal = count
datasetSize := len(datasets)
if datasetSize > 0 {
log.Info("Query private dataset number is:" + fmt.Sprint(datasetSize) + " count=" + fmt.Sprint(count))
makePrivateDataSet(datasets, resultObj, Key)
} else {
log.Info("not found private dataset, keyword=" + Key)
}
if datasetSize >= PageSize {
if WebTotal > 0 { //next page, not first query.
resultObj.Total = int64(WebTotal)
ctx.JSON(200, resultObj)
return
}
}
} else {
resultObj.PrivateTotal = int64(PrivateTotal)
}

from = from - PrivateTotal
if from < 0 {
from = 0
}
Size := PageSize - len(resultObj.Result)

boolQ := elastic.NewBoolQuery() boolQ := elastic.NewBoolQuery()
if Key != "" { if Key != "" {
nameQuery := elastic.NewMatchQuery("title", Key).Boost(2).QueryName("f_first") nameQuery := elastic.NewMatchQuery("title", Key).Boost(2).QueryName("f_first")
@@ -780,24 +825,30 @@ func searchDataSet(ctx *context.Context, TableName string, Key string, Page int,
fileNameQuery := elastic.NewMatchQuery("file_name", Key).Boost(1).QueryName("f_third") fileNameQuery := elastic.NewMatchQuery("file_name", Key).Boost(1).QueryName("f_third")
categoryQuery := elastic.NewMatchQuery("category", Key).Boost(1).QueryName("f_fourth") categoryQuery := elastic.NewMatchQuery("category", Key).Boost(1).QueryName("f_fourth")
boolQ.Should(nameQuery, descQuery, categoryQuery, fileNameQuery) boolQ.Should(nameQuery, descQuery, categoryQuery, fileNameQuery)
res, err := client.Search(TableName).Query(boolQ).SortBy(getSort(SortBy, ascending)).From((Page - 1) * PageSize).Size(PageSize).Highlight(queryHighlight("title", "description", "file_name", "category")).Do(ctx.Req.Context())
res, err := client.Search(TableName).Query(boolQ).SortBy(getSort(SortBy, ascending)).From(from).Size(Size).Highlight(queryHighlight("title", "description", "file_name", "category")).Do(ctx.Req.Context())
if err == nil { if err == nil {
searchJson, _ := json.Marshal(res) searchJson, _ := json.Marshal(res)
log.Info("searchJson=" + string(searchJson)) log.Info("searchJson=" + string(searchJson))
result := makeDatasetResult(res, Key, OnlyReturnNum)
ctx.JSON(200, result)
esresult := makeDatasetResult(res, Key, OnlyReturnNum)
resultObj.Total = resultObj.PrivateTotal + esresult.Total
log.Info("query dataset es count=" + fmt.Sprint(esresult.Total) + " total=" + fmt.Sprint(resultObj.Total))
resultObj.Result = append(resultObj.Result, esresult.Result...)
ctx.JSON(200, resultObj)
} else { } else {
log.Info("query es error," + err.Error()) log.Info("query es error," + err.Error())
} }
} else { } else {
log.Info("query all content.")
log.Info("query all datasets.")
//搜索的属性要指定{"timestamp":{"unmapped_type":"date"}} //搜索的属性要指定{"timestamp":{"unmapped_type":"date"}}
res, err := client.Search(TableName).SortBy(getSort(SortBy, ascending)).From((Page - 1) * PageSize).Size(PageSize).Do(ctx.Req.Context())
res, err := client.Search(TableName).SortBy(getSort(SortBy, ascending)).From(from).Size(Size).Do(ctx.Req.Context())
if err == nil { if err == nil {
searchJson, _ := json.Marshal(res) searchJson, _ := json.Marshal(res)
log.Info("searchJson=" + string(searchJson)) log.Info("searchJson=" + string(searchJson))
result := makeDatasetResult(res, "", OnlyReturnNum)
ctx.JSON(200, result)
esresult := makeDatasetResult(res, "", OnlyReturnNum)
resultObj.Total = resultObj.PrivateTotal + esresult.Total
log.Info("query dataset es count=" + fmt.Sprint(esresult.Total) + " total=" + fmt.Sprint(resultObj.Total))
resultObj.Result = append(resultObj.Result, esresult.Result...)
ctx.JSON(200, resultObj)
} else { } else {
log.Info("query es error," + err.Error()) log.Info("query es error," + err.Error())
ctx.JSON(200, "") ctx.JSON(200, "")
@@ -806,6 +857,42 @@ func searchDataSet(ctx *context.Context, TableName string, Key string, Page int,


} }


func makePrivateDataSet(datasets []*models.Dataset, res *SearchRes, Key string) {
for _, dataset := range datasets {
record := make(map[string]interface{})

record["id"] = dataset.ID
userId := dataset.UserID

user, errUser := models.GetUserByID(userId)
if errUser == nil {
record["owerName"] = user.GetDisplayName()
record["avatar"] = user.RelAvatarLink()
}

repo, errRepo := models.GetRepositoryByID(dataset.RepoID)
if errRepo == nil {
log.Info("repo_url=" + repo.FullName())
record["repoUrl"] = repo.FullName()
record["avatar"] = repo.RelAvatarLink()
} else {
log.Info("repo err=" + errRepo.Error())
}

record["title"] = makeHighLight(Key, dataset.Title)
record["description"] = truncLongText(makeHighLight(Key, dataset.Description), true)

record["category"] = dataset.Category
record["task"] = dataset.Task
record["download_times"] = dataset.DownloadTimes
record["created_unix"] = dataset.CreatedUnix
record["updated_unix"] = repo.UpdatedUnix
record["updated_html"] = timeutil.TimeSinceUnix(repo.UpdatedUnix, "zh-CN")

res.Result = append(res.Result, record)
}
}

func makeDatasetResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool) *SearchRes { func makeDatasetResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool) *SearchRes {
total := sRes.Hits.TotalHits.Value total := sRes.Hits.TotalHits.Value
result := make([]map[string]interface{}, 0) result := make([]map[string]interface{}, 0)


Loading…
Cancel
Save