| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -11,22 +11,38 @@ tags: [Cloudflare, Workers, Vectorize, 博客]
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					# 制作过程 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					## 后端部分 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  其实流程很简单,就是把对应ID的向量查出来之后拿着这个向量再去查询就好了,唯一需要注意的就是它查出来的第一条肯定是自己,所以只要把第一条删掉就行,代码也非常简单:    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  其实流程很简单,就是把对应ID的向量查出来之后拿着这个向量再去查询就好了,唯一需要注意的就是它查出来的第一条肯定是自己,所以只要把第一条删掉就行, ~~代码也非常简单~~ (后来又加了缓存稍微变的复杂了😂):    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					```javascript | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					if (url.pathname.startsWith("/suggest")) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  let resp = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  let update_time = url.searchParams.get('update'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  if (update_time) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    let result = await env.mayx_index.getByIds([ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      query | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    ]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    if (result.length) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      let cache = await db.prepare("SELECT `id`, `suggest`, `suggest_update` FROM `blog_summary` WHERE `id` = ?1") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        .bind(query).first(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      if (!cache.id) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        return Response.json(resp, { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					          headers: commonHeader | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      if (update_time != cache.suggest_update) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        resp = await env.mayx_index.query(result[0].values, { topK: 6 }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        resp = resp.matches; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        resp.splice(0, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        await db.prepare("UPDATE `blog_summary` SET `suggest_update` = ?1, `suggest` = ?2 WHERE `id` = ?3") | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					          .bind(update_time, JSON.stringify(resp), query).run(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        resp = JSON.parse(cache.suggest); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    resp = resp.map(respObj => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      respObj.id = encodeURI(respObj.id); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					      return respObj; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  return Response.json(resp, { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    headers: commonHeader | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  }); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				 | 
				
					@ -37,11 +53,11 @@ if (url.pathname.startsWith("/suggest")) {
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  我还想到一个办法,我之前[给博客做过全文搜索的功能](/2021/07/23/search.html),用这个JS关联查询就能查到标题,而且查不到的内容也显示不出来,这样就能避免有人故意乱上传导致显示奇怪的内容了,不过之前的设计是每次查询都要加载一次包含我文章内容的JSON文件,感觉不太合理,虽然那个文件不算特别大,但是也挺影响速度的,所以我想了一下还是用localStorage缓存一下比较好,所以增加了一个能缓存获取搜索JSON的函数:    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					```javascript | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					function getSearchJSON(callback) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  var searchData = JSON.parse(localStorage.getItem(lastUpdated)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  var searchData = JSON.parse(localStorage.getItem("blog_" + lastUpdated.valueOf())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  if (!searchData) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    localStorage.clear(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    $.getJSON("/search.json", function (data) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        localStorage.setItem(lastUpdated, JSON.stringify(data)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        localStorage.setItem("blog_" + lastUpdated.valueOf(), JSON.stringify(data)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        callback(data); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  } else { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				 | 
				
					@ -49,12 +65,12 @@ function getSearchJSON(callback) {
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					``` | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  做好这个之后就可以做文章推荐的功能了,不过文章推荐应不应该加载完页面就加载呢?其实我测了一下Vectorize数据库的查询速度,不算很慢,但还是需要时间,另外免费版我看了下额度是每月3000万个查询的向量维度,这个其实我没看太懂😂。另外Cloudflare不知道为什么没有展示免费版剩余的额度,而且它是按月计算的,导致我不敢乱用这个查询。 ~~所以我想了一下还是给个按钮来调用吧~~ (后来想了一下干脆直接调用然后加个缓存吧,毕竟我文章不变推荐也不会变)。最终调用的函数如下:    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					  做好这个之后就可以做文章推荐的功能了,不过文章推荐应不应该加载完页面就加载呢?其实我测了一下Vectorize数据库的查询速度,不算很慢,但还是需要时间,另外免费版我看了下额度是每月3000万个查询的向量维度,这个其实我没看太懂😂。另外Cloudflare不知道为什么没有展示免费版剩余的额度,而且它是按月计算的,导致我不敢乱用这个查询。 ~~所以我想了一下还是给个按钮来调用吧~~ (后来想了一下干脆直接调用然后加个缓存吧,毕竟我的文章不变,推荐内容也不会变)。最终调用的函数如下:    | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					```javascript | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					function getSuggestBlog(blogurl) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    var suggest = $("#suggest-container")[0]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    suggest.innerHTML = "Loading..."; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    $.get(BlogAPI + "/suggest?id=" + blogurl, function (data) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					    $.get(BlogAPI + "/suggest?id=" + blogurl + "&update=" + lastUpdated.valueOf(), function (data) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					        if (data.length) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					            getSearchJSON(function (search) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					                suggest.innerHTML = '<b>推荐文章</b><hr style="margin: 0 0 5px"/>'; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				 | 
				
					
 
					 |