mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-18 15:40:12 +01:00
🎨 Return document blocks when search hits different block content https://github.com/siyuan-note/siyuan/issues/10584
This commit is contained in:
parent
a2f4993907
commit
3d5438b91d
1 changed files with 41 additions and 22 deletions
|
|
@ -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)
|
ret, matchedBlockCount, matchedRootCount = searchBySQL("SELECT * FROM `blocks` WHERE `id` = '"+query+"'", beforeLen, page, pageSize)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query = strings.ReplaceAll(query, "'", "''")
|
|
||||||
query = strings.ReplaceAll(query, "\"", "\"\"")
|
|
||||||
return fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy, beforeLen, page, pageSize)
|
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) {
|
func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) {
|
||||||
|
query = stringQuery(query)
|
||||||
table := "blocks_fts" // 大小写敏感
|
table := "blocks_fts" // 大小写敏感
|
||||||
if !Conf.Search.CaseSensitive {
|
if !Conf.Search.CaseSensitive {
|
||||||
table = "blocks_fts_case_insensitive"
|
table = "blocks_fts_case_insensitive"
|
||||||
|
|
@ -1400,15 +1398,6 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri
|
||||||
if !Conf.Search.CaseSensitive {
|
if !Conf.Search.CaseSensitive {
|
||||||
table = "blocks_fts_case_insensitive"
|
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
|
var ignoreFilter string
|
||||||
if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) {
|
if ignoreLines := getSearchIgnoreLines(); 0 < len(ignoreLines) {
|
||||||
|
|
@ -1421,6 +1410,12 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri
|
||||||
ignoreFilter += buf.String()
|
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, " ")
|
keywords := strings.Split(query, " ")
|
||||||
likeFilter := "("
|
likeFilter := "("
|
||||||
for i, keyword := range keywords {
|
for i, keyword := range keywords {
|
||||||
|
|
@ -1431,22 +1426,46 @@ func fullTextSearchByLIKE(query, boxFilter, pathFilter, typeFilter, orderBy stri
|
||||||
}
|
}
|
||||||
likeFilter += ")"
|
likeFilter += ")"
|
||||||
subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" +
|
subquery := "SELECT root_id, GROUP_CONCAT(content) AS docContent" +
|
||||||
" FROM " + table + " WHERE type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter +
|
" FROM " + table + " WHERE type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter +
|
||||||
" GROUP BY root_id HAVING " + likeFilter
|
" GROUP BY root_id HAVING " + likeFilter + orderBy
|
||||||
result, _ := sql.Query(subquery, 10)
|
result, _ := sql.Query(subquery, -1)
|
||||||
var rootIDs []string
|
var rootIDs []string
|
||||||
for _, r := range result {
|
for _, r := range result {
|
||||||
rootIDs = append(rootIDs, r["root_id"].(string))
|
rootIDs = append(rootIDs, r["root_id"].(string))
|
||||||
}
|
}
|
||||||
likeFilter = strings.ReplaceAll(likeFilter, "docContent LIKE", "content LIKE")
|
likeFilter = strings.ReplaceAll(likeFilter, "docContent LIKE", "content LIKE")
|
||||||
stmt := "SELECT " + projections + " FROM " + table + " WHERE" +
|
docMatchStmt := "SELECT * FROM " + table + " WHERE id IN ('" + strings.Join(rootIDs, "','") + "')"
|
||||||
" ((" + likeFilter + " AND root_id IN ('" + strings.Join(rootIDs, "','") + "')) OR" +
|
|
||||||
" (id IN ('" + strings.Join(rootIDs, "','") + "'))) AND" +
|
unionStmt := "SELECT * FROM (" + matchStmt + " UNION ALL " + docMatchStmt + ")"
|
||||||
" type IN " + typeFilter + " " + boxFilter + " " + pathFilter + " " + ignoreFilter
|
countStmt := unionStmt
|
||||||
countStmt := stmt
|
unionStmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize)
|
||||||
stmt += " " + orderBy + " 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)
|
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) {
|
if 1 > len(ret) {
|
||||||
ret = []*Block{}
|
ret = []*Block{}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue