diff --git a/kernel/model/search.go b/kernel/model/search.go index ef4be5674fe..184f88b2551 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -1381,15 +1381,16 @@ func fullTextSearchCountByFTS(query, boxFilter, pathFilter, typeFilter, ignoreFi } func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, ignoreFilter, orderBy string, beforeLen, page, pageSize int) (ret []*Block, matchedBlockCount, matchedRootCount int) { + start := time.Now() + defer func() { + logging.LogInfof("time cost: %v", time.Since(start)) + }() + table := "blocks_fts" // 大小写敏感 if !Conf.Search.CaseSensitive { table = "blocks_fts_case_insensitive" } - mQ := stringQuery(query) - 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, "\"", "\"\"") keywords := strings.Split(query, " ") @@ -1400,11 +1401,13 @@ func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, ignor likeFilter += " AND " } } - dMatchStmt := "SELECT root_id, GROUP_CONCAT(content) AS docContent" + + bMatchStmt := "SELECT id FROM " + table + " WHERE " + strings.ReplaceAll(likeFilter, "docContent LIKE ", "content LIKE ") + bMatchStmt += " AND type IN " + typeFilter + boxFilter + pathFilter + ignoreFilter + dMatchStmt := "SELECT root_id, GROUP_CONCAT(content || tag || name || alias || memo) 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 + ")" - cteStmt += "\nSELECT * FROM " + table + " WHERE id IN (SELECT id FROM blocks) OR id IN (SELECT root_id FROM docs)" + cteStmt := "WITH docBlocks AS (" + dMatchStmt + "), nonDocBlocks AS (" + bMatchStmt + ")" + cteStmt += "\nSELECT * FROM " + table + " WHERE id IN (SELECT id FROM nonDocBlocks) OR id IN (SELECT root_id FROM docBlocks)" countStmt := cteStmt cteStmt += orderBy + " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) resultBlocks := sql.SelectBlocksRawStmtNoParse(cteStmt, -1) @@ -1419,7 +1422,7 @@ func fullTextSearchByFTSWithRoot(query, boxFilter, pathFilter, typeFilter, ignor "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 := "SELECT " + projections + " FROM " + table + " WHERE (`" + table + "` MATCH '" + columnFilter() + ":(" + stringQuery(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) for i, resultBlock := range resultBlocks {