From b1fdfa5539dd5136ac0e863ef7a343b4f44a2d00 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 23 Oct 2024 16:11:13 +0800 Subject: [PATCH 1/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 172 +++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 42 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 751051193..30da6818f 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1280,7 +1280,7 @@ func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, or return } query = stringQuery(query) - return fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) + return fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) } func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { @@ -1350,7 +1350,135 @@ func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy strin ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCount(query, boxFilter, pathFilter, typeFilter) + matchedBlockCount, matchedRootCount = fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter) + return +} + +func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { + if ast.IsNodeIDPattern(query) { + ret, _ := sql.QueryNoLimit("SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE `id` = '" + query + "'") + if 1 > len(ret) { + return + } + matchedBlockCount = int(ret[0]["matches"].(int64)) + matchedRootCount = int(ret[0]["docs"].(int64)) + return + } + + table := "blocks_fts" // 大小写敏感 + if !Conf.Search.CaseSensitive { + table = "blocks_fts_case_insensitive" + } + + stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `" + table + "` WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" + stmt += ") AND type IN " + typeFilter + stmt += boxFilter + pathFilter + + if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { + // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 + buf := bytes.Buffer{} + for _, line := range ignoreLines { + buf.WriteString(" AND ") + buf.WriteString(line) + } + stmt += buf.String() + } + + result, _ := sql.QueryNoLimit(stmt) + if 1 > len(result) { + return + } + matchedBlockCount = int(result[0]["matches"].(int64)) + matchedRootCount = int(result[0]["docs"].(int64)) + return +} + +func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { + table := "blocks_fts" // 大小写敏感 + if !Conf.Search.CaseSensitive { + table = "blocks_fts_case_insensitive" + } + projections := "id, parent_id, root_id, hash, box, path, " + + // Search result content snippet returns more text https://github.com/siyuan-note/siyuan/issues/10707 + "snippet(" + table + ", 6, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS hpath, " + + "snippet(" + table + ", 7, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS name, " + + "snippet(" + table + ", 8, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS alias, " + + "snippet(" + table + ", 9, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS memo, " + + "snippet(" + table + ", 10, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 64) AS tag, " + + "snippet(" + table + ", 11, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS content, " + + "fcontent, markdown, length, type, subtype, ial, sort, created, updated" + subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + + " FROM " + table + " WHERE 1=1" + + " GROUP BY root_id HAVING docContent LIKE '%foo%' AND docContent LIKE '%zzztest%'" + result, _ := sql.Query(subquery, 10) + var rootIDs []string + for _, r := range result { + rootIDs = append(rootIDs, r["root_id"].(string)) + } + + stmt := "SELECT " + projections + " FROM " + table + " WHERE " + + "((content LIKE '%foo%' AND content LIKE '%zzztest%' AND" + + " root_id IN ('" + strings.Join(rootIDs, "','") + "')) OR" + + " (id IN ('" + strings.Join(rootIDs, "','") + "')" + + ")) AND type IN " + typeFilter + " " + boxFilter + " " + pathFilter + if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { + // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 + buf := bytes.Buffer{} + for _, line := range ignoreLines { + buf.WriteString(" AND ") + buf.WriteString(line) + } + stmt += buf.String() + } + + stmt += " " + orderBy + stmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) + ret = fromSQLBlocks(&blocks, "", beforeLen) + if 1 > len(ret) { + ret = []*Block{} + } + + matchedBlockCount, matchedRootCount = fullTextSearchCountByLIKE(query, boxFilter, pathFilter, typeFilter) + return +} + +func fullTextSearchCountByLIKE(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { + if ast.IsNodeIDPattern(query) { + ret, _ := sql.QueryNoLimit("SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE `id` = '" + query + "'") + if 1 > len(ret) { + return + } + matchedBlockCount = int(ret[0]["matches"].(int64)) + matchedRootCount = int(ret[0]["docs"].(int64)) + return + } + + table := "blocks_fts" // 大小写敏感 + if !Conf.Search.CaseSensitive { + table = "blocks_fts_case_insensitive" + } + + stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `" + table + "` WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" + stmt += ") AND type IN " + typeFilter + stmt += boxFilter + pathFilter + + if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { + // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 + buf := bytes.Buffer{} + for _, line := range ignoreLines { + buf.WriteString(" AND ") + buf.WriteString(line) + } + stmt += buf.String() + } + + result, _ := sql.QueryNoLimit(stmt) + if 1 > len(result) { + return + } + matchedBlockCount = int(result[0]["matches"].(int64)) + matchedRootCount = int(result[0]["docs"].(int64)) return } @@ -1399,46 +1527,6 @@ func highlightByRegexp(query, typeFilter, id string) (ret []string) { return } -func fullTextSearchCount(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { - query = filterQueryInvisibleChars(query) - if ast.IsNodeIDPattern(query) { - ret, _ := sql.QueryNoLimit("SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE `id` = '" + query + "'") - if 1 > len(ret) { - return - } - matchedBlockCount = int(ret[0]["matches"].(int64)) - matchedRootCount = int(ret[0]["docs"].(int64)) - return - } - - table := "blocks_fts" // 大小写敏感 - if !Conf.Search.CaseSensitive { - table = "blocks_fts_case_insensitive" - } - - stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `" + table + "` WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" - stmt += ") AND type IN " + typeFilter - stmt += boxFilter + pathFilter - - if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { - // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 - buf := bytes.Buffer{} - for _, line := range ignoreLines { - buf.WriteString(" AND ") - buf.WriteString(line) - } - stmt += buf.String() - } - - result, _ := sql.QueryNoLimit(stmt) - if 1 > len(result) { - return - } - matchedBlockCount = int(result[0]["matches"].(int64)) - matchedRootCount = int(result[0]["docs"].(int64)) - return -} - func markSearch(text string, keyword string, beforeLen int) (marked string, score float64) { if 0 == len(keyword) { marked = text From a2f49939073102c931c413964904f70606c0f260 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 23 Oct 2024 16:45:22 +0800 Subject: [PATCH 2/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 80 +++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 30da6818f..91cce85b8 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1279,7 +1279,9 @@ func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, or ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - query = stringQuery(query) + + query = strings.ReplaceAll(query, "'", "''") + query = strings.ReplaceAll(query, "\"", "\"\"") return fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) } @@ -1407,20 +1409,8 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri "snippet(" + table + ", 10, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 64) AS tag, " + "snippet(" + table + ", 11, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS content, " + "fcontent, markdown, length, type, subtype, ial, sort, created, updated" - subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + - " FROM " + table + " WHERE 1=1" + - " GROUP BY root_id HAVING docContent LIKE '%foo%' AND docContent LIKE '%zzztest%'" - result, _ := sql.Query(subquery, 10) - var rootIDs []string - for _, r := range result { - rootIDs = append(rootIDs, r["root_id"].(string)) - } - stmt := "SELECT " + projections + " FROM " + table + " WHERE " + - "((content LIKE '%foo%' AND content LIKE '%zzztest%' AND" + - " root_id IN ('" + strings.Join(rootIDs, "','") + "')) OR" + - " (id IN ('" + strings.Join(rootIDs, "','") + "')" + - ")) AND type IN " + typeFilter + " " + boxFilter + " " + pathFilter + var ignoreFilter string if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 buf := bytes.Buffer{} @@ -1428,51 +1418,45 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri buf.WriteString(" AND ") buf.WriteString(line) } - stmt += buf.String() + ignoreFilter += buf.String() } - stmt += " " + orderBy - stmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + keywords := strings.Split(query, " ") + likeFilter := "(" + for i, keyword := range keywords { + likeFilter += "docContent LIKE '%" + keyword + "%'" + if i < len(keywords)-1 { + likeFilter += " AND " + } + } + likeFilter += ")" + subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + + " FROM " + table + " WHERE type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter + + " GROUP BY root_id HAVING " + likeFilter + result, _ := sql.Query(subquery, 10) + var rootIDs []string + for _, r := range result { + rootIDs = append(rootIDs, r["root_id"].(string)) + } + likeFilter = strings.ReplaceAll(likeFilter, "docContent LIKE", "content LIKE") + stmt := "SELECT " + projections + " FROM " + table + " WHERE" + + " ((" + likeFilter + " AND root_id IN ('" + strings.Join(rootIDs, "','") + "')) OR" + + " (id IN ('" + strings.Join(rootIDs, "','") + "'))) AND" + + " type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter + countStmt := stmt + stmt += " " + orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) ret = fromSQLBlocks(&blocks, "", beforeLen) if 1 > len(ret) { ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCountByLIKE(query, boxFilter, pathFilter, typeFilter) + matchedBlockCount, matchedRootCount = fullTextSearchCountByLIKE(countStmt) return } -func fullTextSearchCountByLIKE(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { - if ast.IsNodeIDPattern(query) { - ret, _ := sql.QueryNoLimit("SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE `id` = '" + query + "'") - if 1 > len(ret) { - return - } - matchedBlockCount = int(ret[0]["matches"].(int64)) - matchedRootCount = int(ret[0]["docs"].(int64)) - return - } - - table := "blocks_fts" // 大小写敏感 - if !Conf.Search.CaseSensitive { - table = "blocks_fts_case_insensitive" - } - - stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `" + table + "` WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" - stmt += ") AND type IN " + typeFilter - stmt += boxFilter + pathFilter - - if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { - // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 - buf := bytes.Buffer{} - for _, line := range ignoreLines { - buf.WriteString(" AND ") - buf.WriteString(line) - } - stmt += buf.String() - } - +func fullTextSearchCountByLIKE(stmt string) (matchedBlockCount, matchedRootCount int) { + stmt = "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM (" + stmt + ")" result, _ := sql.QueryNoLimit(stmt) if 1 > len(result) { return From 3d5438b91d6a43dd74bdfcc58fb6e0e938a45ff9 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 23 Oct 2024 23:06:48 +0800 Subject: [PATCH 3/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 63 +++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 91cce85b8..8f0efaf11 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1279,9 +1279,6 @@ func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, or ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - - query = strings.ReplaceAll(query, "'", "''") - query = strings.ReplaceAll(query, "\"", "\"\"") return fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) } @@ -1317,6 +1314,7 @@ func fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter string) } func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { + query = stringQuery(query) table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" @@ -1400,15 +1398,6 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" } - projections := "id, parent_id, root_id, hash, box, path, " + - // Search result content snippet returns more text https://github.com/siyuan-note/siyuan/issues/10707 - "snippet(" + table + ", 6, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS hpath, " + - "snippet(" + table + ", 7, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS name, " + - "snippet(" + table + ", 8, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS alias, " + - "snippet(" + table + ", 9, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS memo, " + - "snippet(" + table + ", 10, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 64) AS tag, " + - "snippet(" + table + ", 11, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS content, " + - "fcontent, markdown, length, type, subtype, ial, sort, created, updated" var ignoreFilter string if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { @@ -1421,6 +1410,12 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri ignoreFilter += buf.String() } + mQ := stringQuery(query) + matchStmt := "SELECT * FROM " + table + " WHERE (" + table + " MATCH '" + columnFilter() + ":(" + mQ + ")')" + matchStmt += " AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + + query = strings.ReplaceAll(query, "'", "''") + query = strings.ReplaceAll(query, "\"", "\"\"") keywords := strings.Split(query, " ") likeFilter := "(" for i, keyword := range keywords { @@ -1431,22 +1426,46 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri } likeFilter += ")" subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + - " FROM " + table + " WHERE type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter + - " GROUP BY root_id HAVING " + likeFilter - result, _ := sql.Query(subquery, 10) + " FROM " + table + " WHERE type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + + " GROUP BY root_id HAVING " + likeFilter + orderBy + result, _ := sql.Query(subquery, -1) var rootIDs []string for _, r := range result { rootIDs = append(rootIDs, r["root_id"].(string)) } likeFilter = strings.ReplaceAll(likeFilter, "docContent LIKE", "content LIKE") - stmt := "SELECT " + projections + " FROM " + table + " WHERE" + - " ((" + likeFilter + " AND root_id IN ('" + strings.Join(rootIDs, "','") + "')) OR" + - " (id IN ('" + strings.Join(rootIDs, "','") + "'))) AND" + - " type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter - countStmt := stmt - stmt += " " + orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + docMatchStmt := "SELECT * FROM " + table + " WHERE id IN ('" + strings.Join(rootIDs, "','") + "')" + + unionStmt := "SELECT * FROM (" + matchStmt + " UNION ALL " + docMatchStmt + ")" + countStmt := unionStmt + unionStmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + resultBlocks := sql.SelectBlocksRawStmtNoParse(unionStmt, -1) + + // FTS 高亮 + projections := "id, parent_id, root_id, hash, box, path, " + + // Search result content snippet returns more text https://github.com/siyuan-note/siyuan/issues/10707 + "snippet(" + table + ", 6, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS hpath, " + + "snippet(" + table + ", 7, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS name, " + + "snippet(" + table + ", 8, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS alias, " + + "snippet(" + table + ", 9, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS memo, " + + "snippet(" + table + ", 10, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 64) AS tag, " + + "snippet(" + table + ", 11, '" + search.SearchMarkLeft + "', '" + search.SearchMarkRight + "', '...', 512) AS content, " + + "fcontent, markdown, length, type, subtype, ial, sort, created, updated" + stmt := "SELECT " + projections + " FROM " + table + " WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" + stmt += ") AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) - ret = fromSQLBlocks(&blocks, "", beforeLen) + for i, resultBlock := range resultBlocks { + for j, block := range blocks { + if resultBlock.ID == block.ID { + resultBlocks[i] = block + // 减少 blocks + blocks = append(blocks[:j], blocks[j+1:]...) + break + } + } + } + + ret = fromSQLBlocks(&resultBlocks, "", beforeLen) if 1 > len(ret) { ret = []*Block{} } From 69a1022f8d70199062909fdbe5ccb4678b9c5f5d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Wed, 23 Oct 2024 23:39:03 +0800 Subject: [PATCH 4/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 8f0efaf11..ce7259c58 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1279,7 +1279,7 @@ func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, or ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - return fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) + return fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) } func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { @@ -1393,7 +1393,7 @@ func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) ( return } -func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" @@ -1411,8 +1411,8 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri } mQ := stringQuery(query) - matchStmt := "SELECT * FROM " + table + " WHERE (" + table + " MATCH '" + columnFilter() + ":(" + mQ + ")')" - matchStmt += " AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + bMatchStmt := "SELECT id FROM " + table + " WHERE (" + table + " MATCH '" + columnFilter() + ":(" + mQ + ")')" + bMatchStmt += " AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter query = strings.ReplaceAll(query, "'", "''") query = strings.ReplaceAll(query, "\"", "\"\"") @@ -1425,20 +1425,15 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri } } likeFilter += ")" - subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + + dMatchStmt := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + " FROM " + table + " WHERE type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + - " GROUP BY root_id HAVING " + likeFilter + orderBy - result, _ := sql.Query(subquery, -1) - var rootIDs []string - for _, r := range result { - rootIDs = append(rootIDs, r["root_id"].(string)) - } - likeFilter = strings.ReplaceAll(likeFilter, "docContent LIKE", "content LIKE") - docMatchStmt := "SELECT * FROM " + table + " WHERE id IN ('" + strings.Join(rootIDs, "','") + "')" - - unionStmt := "SELECT * FROM (" + matchStmt + " UNION ALL " + docMatchStmt + ")" + " GROUP BY root_id HAVING " + likeFilter + cteStmt := "WITH docs AS (" + dMatchStmt + "), blocks AS (" + bMatchStmt + ")" + docMatchStmt := "SELECT * FROM " + table + " WHERE id IN (SELECT root_id FROM docs)" + blockMatchStmt := "SELECT * FROM " + table + " WHERE id IN (SELECT id FROM blocks)" + unionStmt := cteStmt + "\nSELECT * FROM (" + blockMatchStmt + " UNION ALL " + docMatchStmt + ")" countStmt := unionStmt - unionStmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + unionStmt += orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) resultBlocks := sql.SelectBlocksRawStmtNoParse(unionStmt, -1) // FTS 高亮 @@ -1470,11 +1465,11 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCountByLIKE(countStmt) + matchedBlockCount, matchedRootCount = fullTextSearchCountByUnion(countStmt) return } -func fullTextSearchCountByLIKE(stmt string) (matchedBlockCount, matchedRootCount int) { +func fullTextSearchCountByUnion(stmt string) (matchedBlockCount, matchedRootCount int) { stmt = "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM (" + stmt + ")" result, _ := sql.QueryNoLimit(stmt) if 1 > len(result) { From ad91c2dfc3c7ad566df7b6326792b78aaec00542 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 24 Oct 2024 00:07:55 +0800 Subject: [PATCH 5/9] :art: Document block sort value changed from `0` to `100` https://github.com/siyuan-note/siyuan/issues/12886 --- kernel/sql/database.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sql/database.go b/kernel/sql/database.go index 4e8ab20b1..45482111d 100644 --- a/kernel/sql/database.go +++ b/kernel/sql/database.go @@ -1422,8 +1422,6 @@ func execStmtTx(tx *sql.Tx, stmt string, args ...interface{}) (err error) { func nSort(n *ast.Node) int { switch n.Type { // 以下为块级元素 - case ast.NodeDocument: - return 0 case ast.NodeHeading: return 5 case ast.NodeParagraph: @@ -1446,6 +1444,8 @@ func nSort(n *ast.Node) int { return 30 case ast.NodeAttributeView: return 30 + case ast.NodeDocument: + return 100 case ast.NodeText, ast.NodeTextMark: if n.IsTextMarkType("tag") { return 205 From 4d1da7bca82051914e01e86eeba2deeeefb64777 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 24 Oct 2024 00:13:10 +0800 Subject: [PATCH 6/9] :art: Document block sort value changed from `0` to `100` https://github.com/siyuan-note/siyuan/issues/12886 --- .../20201222100339-i5hzcph.sy | 171 ++++++++++++---- .../20201222093044-rx4zjoy.sy | 169 ++++++++++++---- .../20211226121808-fnxmngk.sy | 188 ++++++++++++++---- .../20240530101000-58z6rjh.sy | 137 +++++++------ 4 files changed, 487 insertions(+), 178 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy index 7a79958a6..21361de13 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy @@ -6,7 +6,7 @@ "id": "20201222100339-i5hzcph", "title": "Database table", "type": "doc", - "updated": "20221014133135" + "updated": "20241024001049" }, "Children": [ { @@ -689,7 +689,8 @@ "Type": "NodeHeading", "HeadingLevel": 2, "Properties": { - "id": "20201224120448-dd94dgz" + "id": "20201224120448-dd94dgz", + "updated": "20241024001049" }, "Children": [ { @@ -713,7 +714,7 @@ }, "Properties": { "id": "20210112165011-irm4wch", - "updated": "20220427104543" + "updated": "20241024001049" }, "Children": [ { @@ -792,16 +793,21 @@ }, "Properties": { "id": "20210112165011-n8zrkxm", - "updated": "20220312010003" + "updated": "20241024001049" }, "Children": [ { "ID": "20210210104251-nno6rgh", "Type": "NodeParagraph", "Properties": { - "id": "20210210104251-nno6rgh" + "id": "20210210104251-nno6rgh", + "updated": "20210210104251" }, "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, { "Type": "NodeTextMark", "TextMarkType": "code", @@ -809,7 +815,7 @@ }, { "Type": "NodeText", - "Data": " field" + "Data": "​ field" } ] }, @@ -819,40 +825,9 @@ "ListData": {}, "Properties": { "id": "20210112165011-fodiphq", - "updated": "20220312010003" + "updated": "20241024001049" }, "Children": [ - { - "ID": "20210112165011-hb9w8kd", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20210112165011-hb9w8kd" - }, - "Children": [ - { - "ID": "20210210104251-iy9ugib", - "Type": "NodeParagraph", - "Properties": { - "id": "20210210104251-iy9ugib" - }, - "Children": [ - { - "Type": "NodeText", - "Data": "Document block: " - }, - { - "Type": "NodeTextMark", - "TextMarkType": "code", - "TextMarkTextContent": "0" - } - ] - } - ] - }, { "ID": "20210112165011-epgryib", "Type": "NodeListItem", @@ -861,14 +836,16 @@ "Marker": "Kg==" }, "Properties": { - "id": "20210112165011-epgryib" + "id": "20210112165011-epgryib", + "updated": "20210112165011" }, "Children": [ { "ID": "20210210104251-blu4b7p", "Type": "NodeParagraph", "Properties": { - "id": "20210210104251-blu4b7p" + "id": "20210210104251-blu4b7p", + "updated": "20210210104251" }, "Children": [ { @@ -879,6 +856,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "5" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -912,6 +893,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -945,6 +930,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -978,6 +967,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1011,6 +1004,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1044,6 +1041,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1077,6 +1078,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1110,6 +1115,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1143,6 +1152,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1176,6 +1189,84 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024001044-dcps4dt", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001044-dcps4dt", + "updated": "20241024001049" + }, + "Children": [ + { + "ID": "20241024001044-99gyvks", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001044-99gyvks", + "updated": "20241024001049" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "Database block: " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024001039-ohxxgjo", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001039-ohxxgjo", + "updated": "20241024001039" + }, + "Children": [ + { + "ID": "20241024001039-pm9zy3x", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001039-pm9zy3x", + "updated": "20241024001041" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "Document block: " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "100" + }, + { + "Type": "NodeText", + "Data": "​" } ] } diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy index 2c4e6828b..28ce1f525 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy @@ -6,7 +6,7 @@ "id": "20201222093044-rx4zjoy", "title": "数据库表", "type": "doc", - "updated": "20221014133123" + "updated": "20210210103236" }, "Children": [ { @@ -689,7 +689,8 @@ "Type": "NodeHeading", "HeadingLevel": 2, "Properties": { - "id": "20201224120447-lezmdb3" + "id": "20201224120447-lezmdb3", + "updated": "20210210103236" }, "Children": [ { @@ -713,7 +714,7 @@ }, "Properties": { "id": "20201224120447-ij3ivd5", - "updated": "20220427104619" + "updated": "20210210103236" }, "Children": [ { @@ -796,16 +797,21 @@ }, "Properties": { "id": "20210112160050-sd8nvwk", - "updated": "20220312005741" + "updated": "20210210103236" }, "Children": [ { "ID": "20210210103236-4q63z1f", "Type": "NodeParagraph", "Properties": { - "id": "20210210103236-4q63z1f" + "id": "20210210103236-4q63z1f", + "updated": "20210210103236" }, "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, { "Type": "NodeTextMark", "TextMarkType": "code", @@ -813,7 +819,7 @@ }, { "Type": "NodeText", - "Data": " 字段" + "Data": "​ 字段" } ] }, @@ -826,37 +832,6 @@ "updated": "20220312005741" }, "Children": [ - { - "ID": "20210112160058-9fxe2cs", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20210112160058-9fxe2cs" - }, - "Children": [ - { - "ID": "20210210103236-i2foidw", - "Type": "NodeParagraph", - "Properties": { - "id": "20210210103236-i2foidw" - }, - "Children": [ - { - "Type": "NodeText", - "Data": "文档块:" - }, - { - "Type": "NodeTextMark", - "TextMarkType": "code", - "TextMarkTextContent": "0" - } - ] - } - ] - }, { "ID": "20210112160120-74nf28j", "Type": "NodeListItem", @@ -865,14 +840,16 @@ "Marker": "Kg==" }, "Properties": { - "id": "20210112160120-74nf28j" + "id": "20210112160120-74nf28j", + "updated": "20210112160120" }, "Children": [ { "ID": "20210210103236-f9jdxfd", "Type": "NodeParagraph", "Properties": { - "id": "20210210103236-f9jdxfd" + "id": "20210210103236-f9jdxfd", + "updated": "20210210103236" }, "Children": [ { @@ -883,6 +860,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "5" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -916,6 +897,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -949,6 +934,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -982,6 +971,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1015,6 +1008,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1048,6 +1045,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1081,6 +1082,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1114,6 +1119,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1147,6 +1156,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1180,6 +1193,84 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024000912-uo2zwia", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024000912-uo2zwia", + "updated": "20241024000912" + }, + "Children": [ + { + "ID": "20241024000912-xai3l1p", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024000912-xai3l1p", + "updated": "20241024000917" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "数据库块:" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024000917-3vhxi15", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024000917-3vhxi15", + "updated": "20241024000917" + }, + "Children": [ + { + "ID": "20241024000917-xs7tchv", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024000917-xs7tchv", + "updated": "20241024000921" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "文档块:" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "100" + }, + { + "Type": "NodeText", + "Data": "​" } ] } diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy index 0c4643cfc..ab76ef8b2 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy @@ -5,7 +5,8 @@ "Properties": { "id": "20211226121808-fnxmngk", "title": "資料庫表", - "updated": "20230630110035" + "type": "doc", + "updated": "20211228134348" }, "Children": [ { @@ -686,7 +687,7 @@ "HeadingLevel": 2, "Properties": { "id": "20211226121831-zvnhouv", - "updated": "20211228132848" + "updated": "20211228134348" }, "Children": [ { @@ -701,7 +702,7 @@ "ListData": {}, "Properties": { "id": "20211226121831-oj726eb", - "updated": "20230630110035" + "updated": "20211228134348" }, "Children": [ { @@ -777,7 +778,7 @@ }, "Properties": { "id": "20211226121831-zs0ji69", - "updated": "20220312005849" + "updated": "20211228134348" }, "Children": [ { @@ -788,6 +789,10 @@ "updated": "20211228134348" }, "Children": [ + { + "Type": "NodeText", + "Data": "​" + }, { "Type": "NodeTextMark", "TextMarkType": "code", @@ -795,7 +800,7 @@ }, { "Type": "NodeText", - "Data": " 欄位" + "Data": "​ 欄位" } ] }, @@ -808,37 +813,6 @@ "updated": "20220312005849" }, "Children": [ - { - "ID": "20211226121831-0ko7h04", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "id": "20211226121831-0ko7h04" - }, - "Children": [ - { - "ID": "20211226121831-twcl260", - "Type": "NodeParagraph", - "Properties": { - "id": "20211226121831-twcl260" - }, - "Children": [ - { - "Type": "NodeText", - "Data": "文檔塊:" - }, - { - "Type": "NodeTextMark", - "TextMarkType": "code", - "TextMarkTextContent": "0" - } - ] - } - ] - }, { "ID": "20211226121831-vs8zc2q", "Type": "NodeListItem", @@ -847,14 +821,16 @@ "Marker": "Kg==" }, "Properties": { - "id": "20211226121831-vs8zc2q" + "id": "20211226121831-vs8zc2q", + "updated": "20211226121831" }, "Children": [ { "ID": "20211226121831-f2bpy1c", "Type": "NodeParagraph", "Properties": { - "id": "20211226121831-f2bpy1c" + "id": "20211226121831-f2bpy1c", + "updated": "20211226121831" }, "Children": [ { @@ -865,6 +841,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "5" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -898,6 +878,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -931,6 +915,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -964,6 +952,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -997,6 +989,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1030,6 +1026,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "10" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1063,6 +1063,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1096,6 +1100,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1129,6 +1137,10 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "20" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1162,6 +1174,84 @@ "Type": "NodeTextMark", "TextMarkType": "code", "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024001004-ua7jo68", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001004-ua7jo68", + "updated": "20241024001004" + }, + "Children": [ + { + "ID": "20241024001004-wu134y6", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001004-wu134y6", + "updated": "20241024001020" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "資料庫塊:" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024001004-awor1zs", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001004-awor1zs", + "updated": "20241024001004" + }, + "Children": [ + { + "ID": "20241024001004-wtbxwea", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001004-wtbxwea", + "updated": "20241024001019" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "文檔塊:" + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "100" + }, + { + "Type": "NodeText", + "Data": "​" } ] } @@ -1170,6 +1260,28 @@ ] } ] + }, + { + "ID": "20241024000958-wx7ry0w", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024000958-wx7ry0w", + "updated": "20241024000958" + }, + "Children": [ + { + "ID": "20241024000958-9qbls2u", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024000958-9qbls2u", + "updated": "20241024000958" + } + } + ] } ] } diff --git a/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy b/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy index b2e4a48b2..56a9f056d 100644 --- a/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy +++ b/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy @@ -818,7 +818,6 @@ "ID": "20240530101000-mne3cfq", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-zat4xji", "id": "20240530101000-mne3cfq", "updated": "20240530101000" }, @@ -843,49 +842,10 @@ "Type": "NodeList", "ListData": {}, "Properties": { - "ID": "20240530101000-2cxguwt", "id": "20240530101000-8rv3wzu", "updated": "20240530101000" }, "Children": [ - { - "ID": "20240530101000-gholggk", - "Type": "NodeListItem", - "ListData": { - "BulletChar": 42, - "Marker": "Kg==" - }, - "Properties": { - "ID": "20240530101000-13st18e", - "id": "20240530101000-gholggk" - }, - "Children": [ - { - "ID": "20240530101000-6bl43rm", - "Type": "NodeParagraph", - "Properties": { - "ID": "20240530101000-mjdpqnn", - "id": "20240530101000-6bl43rm", - "updated": "20240530101000" - }, - "Children": [ - { - "Type": "NodeText", - "Data": "ドキュメントブロック: " - }, - { - "Type": "NodeTextMark", - "TextMarkType": "code", - "TextMarkTextContent": "0" - }, - { - "Type": "NodeText", - "Data": "​" - } - ] - } - ] - }, { "ID": "20240530101000-bbi6u3a", "Type": "NodeListItem", @@ -894,15 +854,14 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-73yi5ls", - "id": "20240530101000-bbi6u3a" + "id": "20240530101000-bbi6u3a", + "updated": "20240530101000" }, "Children": [ { "ID": "20240530101000-hazo7qh", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-6tc0as0", "id": "20240530101000-hazo7qh", "updated": "20240530101000" }, @@ -932,7 +891,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-jjy3ouk", "id": "20240530101000-vmb7t9y", "updated": "20240530101000" }, @@ -941,7 +899,6 @@ "ID": "20240530101000-crv9hv9", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-mr7pw7r", "id": "20240530101000-crv9hv9", "updated": "20240530101000" }, @@ -971,7 +928,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-cyc3wg7", "id": "20240530101000-8u5e3kt", "updated": "20240530101000" }, @@ -980,7 +936,6 @@ "ID": "20240530101000-o40x5nb", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-pvgr1e1", "id": "20240530101000-o40x5nb", "updated": "20240530101000" }, @@ -1010,7 +965,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-iuogeyw", "id": "20240530101000-m24vrgz", "updated": "20240530101000" }, @@ -1019,7 +973,6 @@ "ID": "20240530101000-siukphp", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-0ewvks9", "id": "20240530101000-siukphp", "updated": "20240530101000" }, @@ -1049,7 +1002,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-l6xju21", "id": "20240530101000-v2gkqj8", "updated": "20240530101000" }, @@ -1058,7 +1010,6 @@ "ID": "20240530101000-t7mgtfk", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-8s1lmsc", "id": "20240530101000-t7mgtfk", "updated": "20240530101000" }, @@ -1088,7 +1039,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-n58qmno", "id": "20240530101000-94lacat", "updated": "20240530101000" }, @@ -1097,7 +1047,6 @@ "ID": "20240530101000-o40rn1y", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-6zfuf1k", "id": "20240530101000-o40rn1y", "updated": "20240530101000" }, @@ -1127,7 +1076,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-9fnnx0z", "id": "20240530101000-vad5ds7", "updated": "20240530101000" }, @@ -1136,7 +1084,6 @@ "ID": "20240530101000-fszxybt", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-ud5qscz", "id": "20240530101000-fszxybt", "updated": "20240530101000" }, @@ -1166,7 +1113,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-vsf16ms", "id": "20240530101000-bg5woa1", "updated": "20240530101000" }, @@ -1175,7 +1121,6 @@ "ID": "20240530101000-vz5x0vh", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-pdokiyu", "id": "20240530101000-vz5x0vh", "updated": "20240530101000" }, @@ -1205,7 +1150,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-cue1u5r", "id": "20240530101000-szwjkk8", "updated": "20240530101000" }, @@ -1214,7 +1158,6 @@ "ID": "20240530101000-hrexfa7", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-mxkgtk1", "id": "20240530101000-hrexfa7", "updated": "20240530101000" }, @@ -1244,7 +1187,6 @@ "Marker": "Kg==" }, "Properties": { - "ID": "20240530101000-r4vi4kx", "id": "20240530101000-n8p7p53", "updated": "20240530101000" }, @@ -1253,7 +1195,6 @@ "ID": "20240530101000-d1jth4r", "Type": "NodeParagraph", "Properties": { - "ID": "20240530101000-4jp6zai", "id": "20240530101000-d1jth4r", "updated": "20240530101000" }, @@ -1274,6 +1215,80 @@ ] } ] + }, + { + "ID": "20241024001112-d1aen8d", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001112-d1aen8d", + "updated": "20241024001112" + }, + "Children": [ + { + "ID": "20241024001112-xvg1o5n", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001112-xvg1o5n", + "updated": "20241024001114" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "データベースブロック: " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "30" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] + }, + { + "ID": "20241024001115-q3v9s9k", + "Type": "NodeListItem", + "ListData": { + "BulletChar": 42, + "Marker": "Kg==" + }, + "Properties": { + "id": "20241024001115-q3v9s9k", + "updated": "20241024001115" + }, + "Children": [ + { + "ID": "20241024001115-xn6pni8", + "Type": "NodeParagraph", + "Properties": { + "id": "20241024001115-xn6pni8", + "updated": "20241024001115" + }, + "Children": [ + { + "Type": "NodeText", + "Data": "ドキュメントブロック: " + }, + { + "Type": "NodeTextMark", + "TextMarkType": "code", + "TextMarkTextContent": "100" + }, + { + "Type": "NodeText", + "Data": "​" + } + ] + } + ] } ] } From 3ba6dfed83be0d32ca94da0a254a7cd7c7836d9d Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 24 Oct 2024 00:13:33 +0800 Subject: [PATCH 7/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index ce7259c58..8050e6f45 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1279,7 +1279,7 @@ func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, or ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - return fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) + return fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) } func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { @@ -1393,7 +1393,7 @@ func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) ( return } -func fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" @@ -1417,24 +1417,21 @@ func fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy str query = strings.ReplaceAll(query, "'", "''") query = strings.ReplaceAll(query, "\"", "\"\"") keywords := strings.Split(query, " ") - likeFilter := "(" + var likeFilter string for i, keyword := range keywords { likeFilter += "docContent LIKE '%" + keyword + "%'" if i < len(keywords)-1 { likeFilter += " AND " } } - likeFilter += ")" dMatchStmt := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + " FROM " + table + " WHERE type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + " GROUP BY root_id HAVING " + likeFilter cteStmt := "WITH docs AS (" + dMatchStmt + "), blocks AS (" + bMatchStmt + ")" - docMatchStmt := "SELECT * FROM " + table + " WHERE id IN (SELECT root_id FROM docs)" - blockMatchStmt := "SELECT * FROM " + table + " WHERE id IN (SELECT id FROM blocks)" - unionStmt := cteStmt + "\nSELECT * FROM (" + blockMatchStmt + " UNION ALL " + docMatchStmt + ")" - countStmt := unionStmt - unionStmt += orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) - resultBlocks := sql.SelectBlocksRawStmtNoParse(unionStmt, -1) + cteStmt += "\nSELECT * FROM " + table + " WHERE id IN (SELECT id FROM blocks) OR id IN (SELECT root_id FROM docs)" + countStmt := cteStmt + cteStmt += orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) + resultBlocks := sql.SelectBlocksRawStmtNoParse(cteStmt, -1) // FTS 高亮 projections := "id, parent_id, root_id, hash, box, path, " + @@ -1465,11 +1462,11 @@ func fullTextSearchByUnion(query, boxFilter, pathFilter, typeFilter, orderBy str ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCountByUnion(countStmt) + matchedBlockCount, matchedRootCount = fullTextSearchCountByStmt(countStmt) return } -func fullTextSearchCountByUnion(stmt string) (matchedBlockCount, matchedRootCount int) { +func fullTextSearchCountByStmt(stmt string) (matchedBlockCount, matchedRootCount int) { stmt = "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM (" + stmt + ")" result, _ := sql.QueryNoLimit(stmt) if 1 > len(result) { From da341269cda8f81f76aad77a8f2c49178352a0a4 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 24 Oct 2024 00:27:26 +0800 Subject: [PATCH 8/9] :art: Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584 --- kernel/model/search.go | 87 ++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 55 deletions(-) diff --git a/kernel/model/search.go b/kernel/model/search.go index 8050e6f45..f9422088d 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -914,27 +914,39 @@ func FullTextSearchBlock(query string, boxes, paths []string, types map[string]b query = trimQuery } + var ignoreFilter string + if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { + // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 + buf := bytes.Buffer{} + for _, line := range ignoreLines { + buf.WriteString(" AND ") + buf.WriteString(line) + } + ignoreFilter += buf.String() + } + beforeLen := 36 var blocks []*Block orderByClause := buildOrderBy(query, method, orderBy) switch method { case 1: // 查询语法 - filter := buildTypeFilter(types) + typeFilter := buildTypeFilter(types) boxFilter := buildBoxesFilter(boxes) pathFilter := buildPathsFilter(paths) - blocks, matchedBlockCount, matchedRootCount = fullTextSearchByQuerySyntax(query, boxFilter, pathFilter, filter, orderByClause, beforeLen, page, pageSize) + blocks, matchedBlockCount, matchedRootCount = fullTextSearchByQuerySyntax(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderByClause, beforeLen, page, pageSize) case 2: // SQL blocks, matchedBlockCount, matchedRootCount = searchBySQL(query, beforeLen, page, pageSize) case 3: // 正则表达式 typeFilter := buildTypeFilter(types) boxFilter := buildBoxesFilter(boxes) pathFilter := buildPathsFilter(paths) - blocks, matchedBlockCount, matchedRootCount = fullTextSearchByRegexp(query, boxFilter, pathFilter, typeFilter, orderByClause, beforeLen, page, pageSize) + blocks, matchedBlockCount, matchedRootCount = fullTextSearchByRegexp(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderByClause, beforeLen, page, pageSize) default: // 关键字 - filter := buildTypeFilter(types) + typeFilter := buildTypeFilter(types) boxFilter := buildBoxesFilter(boxes) pathFilter := buildPathsFilter(paths) - blocks, matchedBlockCount, matchedRootCount = fullTextSearchByKeyword(query, boxFilter, pathFilter, filter, orderByClause, beforeLen, page, pageSize) + + blocks, matchedBlockCount, matchedRootCount = fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderByClause, beforeLen, page, pageSize) } pageCount = (matchedBlockCount + pageSize - 1) / pageSize @@ -1264,31 +1276,30 @@ func extractID(content string) (ret string) { return } -func fullTextSearchByQuerySyntax(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByQuerySyntax(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { query = filterQueryInvisibleChars(query) if ast.IsNodeIDPattern(query) { ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - return fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) + return fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy, beforeLen, page, pageSize) } -func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter string, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter, ignoreFilter string, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { query = filterQueryInvisibleChars(query) if ast.IsNodeIDPattern(query) { ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize) return } - return fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize) + return fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy, beforeLen, page, pageSize) } -func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { exp = filterQueryInvisibleChars(exp) fieldFilter := fieldRegexp(exp) stmt := "SELECT * FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter - stmt += boxFilter + pathFilter - stmt += " " + orderBy + stmt += boxFilter + pathFilter + ignoreFilter + " " + orderBy regex := regexp.MustCompile(exp) blocks := sql.SelectBlocksRegex(stmt, regex, Conf.Search.Name, Conf.Search.Alias, Conf.Search.Memo, Conf.Search.IAL, page, pageSize) ret = fromSQLBlocks(&blocks, "", beforeLen) @@ -1296,13 +1307,13 @@ func fullTextSearchByRegexp(exp, boxFilter, pathFilter, typeFilter, orderBy stri ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter) + matchedBlockCount, matchedRootCount = fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter, ignoreFilter) return } -func fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { +func fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter, ignoreFilter string) (matchedBlockCount, matchedRootCount int) { fieldFilter := fieldRegexp(exp) - stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter + stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE " + fieldFilter + " AND type IN " + typeFilter + ignoreFilter stmt += boxFilter + pathFilter result, _ := sql.QueryNoLimit(stmt) if 1 > len(result) { @@ -1313,7 +1324,7 @@ func fullTextSearchCountByRegexp(exp, boxFilter, pathFilter, typeFilter string) return } -func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { query = stringQuery(query) table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { @@ -1330,19 +1341,7 @@ func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy strin "fcontent, markdown, length, type, subtype, ial, sort, created, updated" stmt := "SELECT " + projections + " FROM " + table + " WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" stmt += ") AND type IN " + typeFilter - stmt += boxFilter + pathFilter - - if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { - // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 - buf := bytes.Buffer{} - for _, line := range ignoreLines { - buf.WriteString(" AND ") - buf.WriteString(line) - } - stmt += buf.String() - } - - stmt += " " + orderBy + stmt += boxFilter + pathFilter + ignoreFilter + " " + orderBy stmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) ret = fromSQLBlocks(&blocks, "", beforeLen) @@ -1350,11 +1349,11 @@ func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy strin ret = []*Block{} } - matchedBlockCount, matchedRootCount = fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter) + matchedBlockCount, matchedRootCount = fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter, ignoreFilter) return } -func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) (matchedBlockCount, matchedRootCount int) { +func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter, ignoreFilter string) (matchedBlockCount, matchedRootCount int) { if ast.IsNodeIDPattern(query) { ret, _ := sql.QueryNoLimit("SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `blocks` WHERE `id` = '" + query + "'") if 1 > len(ret) { @@ -1372,18 +1371,7 @@ func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) ( stmt := "SELECT COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` FROM `" + table + "` WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + query + ")'" stmt += ") AND type IN " + typeFilter - stmt += boxFilter + pathFilter - - if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { - // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 - buf := bytes.Buffer{} - for _, line := range ignoreLines { - buf.WriteString(" AND ") - buf.WriteString(line) - } - stmt += buf.String() - } - + stmt += boxFilter + pathFilter + ignoreFilter result, _ := sql.QueryNoLimit(stmt) if 1 > len(result) { return @@ -1393,23 +1381,12 @@ func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter string) ( return } -func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { +func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" } - var ignoreFilter string - if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) { - // Support ignore search results https://github.com/siyuan-note/siyuan/issues/10089 - buf := bytes.Buffer{} - for _, line := range ignoreLines { - buf.WriteString(" AND ") - buf.WriteString(line) - } - ignoreFilter += buf.String() - } - mQ := stringQuery(query) bMatchStmt := "SELECT id FROM " + table + " WHERE (" + table + " MATCH '" + columnFilter() + ":(" + mQ + ")')" bMatchStmt += " AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter From 94f378aa553aa8d523dde1a4df8cecbf72ac32cb Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Thu, 24 Oct 2024 01:08:10 +0800 Subject: [PATCH 9/9] :rewind: Revert Document block sort value changed from `0` to `100` https://github.com/siyuan-note/siyuan/issues/12886 --- .../20201222100339-i5hzcph.sy | 16 ++++++++-------- .../20201222093044-rx4zjoy.sy | 16 ++++++++-------- .../20211226121808-fnxmngk.sy | 16 ++++++++-------- .../20240530101000-58z6rjh.sy | 16 ++++++++-------- kernel/model/search.go | 1 - kernel/sql/database.go | 2 +- 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy index 21361de13..5ff061f46 100644 --- a/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy +++ b/app/guide/20210808180117-6v0mkxr/20200923234011-ieuun1p/20210808180303-l3qg72k/20201222100339-i5hzcph.sy @@ -6,7 +6,7 @@ "id": "20201222100339-i5hzcph", "title": "Database table", "type": "doc", - "updated": "20241024001049" + "updated": "20241024010556" }, "Children": [ { @@ -690,7 +690,7 @@ "HeadingLevel": 2, "Properties": { "id": "20201224120448-dd94dgz", - "updated": "20241024001049" + "updated": "20241024010556" }, "Children": [ { @@ -714,7 +714,7 @@ }, "Properties": { "id": "20210112165011-irm4wch", - "updated": "20241024001049" + "updated": "20241024010556" }, "Children": [ { @@ -793,7 +793,7 @@ }, "Properties": { "id": "20210112165011-n8zrkxm", - "updated": "20241024001049" + "updated": "20241024010556" }, "Children": [ { @@ -825,7 +825,7 @@ "ListData": {}, "Properties": { "id": "20210112165011-fodiphq", - "updated": "20241024001049" + "updated": "20241024010556" }, "Children": [ { @@ -1244,7 +1244,7 @@ }, "Properties": { "id": "20241024001039-ohxxgjo", - "updated": "20241024001039" + "updated": "20241024010556" }, "Children": [ { @@ -1252,7 +1252,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20241024001039-pm9zy3x", - "updated": "20241024001041" + "updated": "20241024010556" }, "Children": [ { @@ -1262,7 +1262,7 @@ { "Type": "NodeTextMark", "TextMarkType": "code", - "TextMarkTextContent": "100" + "TextMarkTextContent": "0" }, { "Type": "NodeText", diff --git a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy index 28ce1f525..82581fc56 100644 --- a/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy +++ b/app/guide/20210808180117-czj9bvb/20200812220555-lj3enxa/20210808180320-gyngv2x/20201222093044-rx4zjoy.sy @@ -6,7 +6,7 @@ "id": "20201222093044-rx4zjoy", "title": "数据库表", "type": "doc", - "updated": "20210210103236" + "updated": "20241024010538" }, "Children": [ { @@ -690,7 +690,7 @@ "HeadingLevel": 2, "Properties": { "id": "20201224120447-lezmdb3", - "updated": "20210210103236" + "updated": "20241024010538" }, "Children": [ { @@ -714,7 +714,7 @@ }, "Properties": { "id": "20201224120447-ij3ivd5", - "updated": "20210210103236" + "updated": "20241024010538" }, "Children": [ { @@ -797,7 +797,7 @@ }, "Properties": { "id": "20210112160050-sd8nvwk", - "updated": "20210210103236" + "updated": "20241024010538" }, "Children": [ { @@ -829,7 +829,7 @@ "ListData": {}, "Properties": { "id": "20210112160059-bc0lg2b", - "updated": "20220312005741" + "updated": "20241024010538" }, "Children": [ { @@ -1248,7 +1248,7 @@ }, "Properties": { "id": "20241024000917-3vhxi15", - "updated": "20241024000917" + "updated": "20241024010538" }, "Children": [ { @@ -1256,7 +1256,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20241024000917-xs7tchv", - "updated": "20241024000921" + "updated": "20241024010538" }, "Children": [ { @@ -1266,7 +1266,7 @@ { "Type": "NodeTextMark", "TextMarkType": "code", - "TextMarkTextContent": "100" + "TextMarkTextContent": "0" }, { "Type": "NodeText", diff --git a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy index ab76ef8b2..f1944b4d1 100644 --- a/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy +++ b/app/guide/20211226090932-5lcq56f/20211226115423-d5z1joq/20211226120933-vnjgwwh/20211226121808-fnxmngk.sy @@ -6,7 +6,7 @@ "id": "20211226121808-fnxmngk", "title": "資料庫表", "type": "doc", - "updated": "20211228134348" + "updated": "20241024010548" }, "Children": [ { @@ -687,7 +687,7 @@ "HeadingLevel": 2, "Properties": { "id": "20211226121831-zvnhouv", - "updated": "20211228134348" + "updated": "20241024010548" }, "Children": [ { @@ -702,7 +702,7 @@ "ListData": {}, "Properties": { "id": "20211226121831-oj726eb", - "updated": "20211228134348" + "updated": "20241024010548" }, "Children": [ { @@ -778,7 +778,7 @@ }, "Properties": { "id": "20211226121831-zs0ji69", - "updated": "20211228134348" + "updated": "20241024010548" }, "Children": [ { @@ -810,7 +810,7 @@ "ListData": {}, "Properties": { "id": "20211226121831-6ak7dij", - "updated": "20220312005849" + "updated": "20241024010548" }, "Children": [ { @@ -1229,7 +1229,7 @@ }, "Properties": { "id": "20241024001004-awor1zs", - "updated": "20241024001004" + "updated": "20241024010548" }, "Children": [ { @@ -1237,7 +1237,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20241024001004-wtbxwea", - "updated": "20241024001019" + "updated": "20241024010548" }, "Children": [ { @@ -1247,7 +1247,7 @@ { "Type": "NodeTextMark", "TextMarkType": "code", - "TextMarkTextContent": "100" + "TextMarkTextContent": "0" }, { "Type": "NodeText", diff --git a/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy b/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy index 56a9f056d..14b1c9b6d 100644 --- a/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy +++ b/app/guide/20240530133126-axarxgx/20240530101000-4qitucx/20240530101000-a91lmk2/20240530101000-58z6rjh.sy @@ -7,7 +7,7 @@ "id": "20240530101000-58z6rjh", "title": "データベーステーブル", "type": "doc", - "updated": "20240530101000" + "updated": "20241024010606" }, "Children": [ { @@ -704,7 +704,7 @@ "Properties": { "ID": "20240530101000-hotqrms", "id": "20240530101000-214gvio", - "updated": "20240530101000" + "updated": "20241024010606" }, "Children": [ { @@ -725,7 +725,7 @@ "Properties": { "ID": "20240530101000-e9bmqha", "id": "20240530101000-4hc7zl9", - "updated": "20240530101000" + "updated": "20241024010606" }, "Children": [ { @@ -811,7 +811,7 @@ "Properties": { "ID": "20240530101000-rsk9w3i", "id": "20240530101000-7pu1enh", - "updated": "20240530101000" + "updated": "20241024010606" }, "Children": [ { @@ -843,7 +843,7 @@ "ListData": {}, "Properties": { "id": "20240530101000-8rv3wzu", - "updated": "20240530101000" + "updated": "20241024010606" }, "Children": [ { @@ -1262,7 +1262,7 @@ }, "Properties": { "id": "20241024001115-q3v9s9k", - "updated": "20241024001115" + "updated": "20241024010606" }, "Children": [ { @@ -1270,7 +1270,7 @@ "Type": "NodeParagraph", "Properties": { "id": "20241024001115-xn6pni8", - "updated": "20241024001115" + "updated": "20241024010606" }, "Children": [ { @@ -1280,7 +1280,7 @@ { "Type": "NodeTextMark", "TextMarkType": "code", - "TextMarkTextContent": "100" + "TextMarkTextContent": "0" }, { "Type": "NodeText", diff --git a/kernel/model/search.go b/kernel/model/search.go index f9422088d..ef4be5674 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -945,7 +945,6 @@ func FullTextSearchBlock(query string, boxes, paths []string, types map[string]b typeFilter := buildTypeFilter(types) boxFilter := buildBoxesFilter(boxes) pathFilter := buildPathsFilter(paths) - blocks, matchedBlockCount, matchedRootCount = fullTextSearchByKeyword(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderByClause, beforeLen, page, pageSize) } pageCount = (matchedBlockCount + pageSize - 1) / pageSize diff --git a/kernel/sql/database.go b/kernel/sql/database.go index 45482111d..e35008e66 100644 --- a/kernel/sql/database.go +++ b/kernel/sql/database.go @@ -1445,7 +1445,7 @@ func nSort(n *ast.Node) int { case ast.NodeAttributeView: return 30 case ast.NodeDocument: - return 100 + return 0 case ast.NodeText, ast.NodeTextMark: if n.IsTextMarkType("tag") { return 205