全文搜索

通过关键字快速查找笔记正文以及标题内容。


准备工作

  • 先去 algolia 官网 提交你的网站,注意:需要一个 Github 仓库地址,可选择部分内容上传到这个仓库
  • 大概等了两天就会收到 algolia 的邮件,你需要回复此邮件,回复内容:"Thanks, I am the maintainer of the website,I can add javascript code to my website."
  • 大概几个小时后会收到 algolia 发给你的 javascript 代码片段,复制这些代码以待处理


编写配置文件

将如下内容粘贴到 algolia 管理后台 配置文件中:

点击查看配置文件代码
new Crawler({
  rateLimit: 8,
  sitemaps: ["https://www.echoxu.cn/sitemap.xml"], // 因为使用了 sitemap 所以就不用填写 startUrls: ["https://www.echoxu.cn/"],
  renderJavaScript: true,
  ignoreCanonicalTo: false,
  discoveryPatterns: ["https://www.echoxu.cn/**"],
  // 如果网站内容改动不是很频繁时可设置 algolia 不要每天进行爬取,减小服务器的压力,每天爬取:"at 02:00 every 1 day",
  schedule: "at 12:00 am on Mon", 
  actions: [
    {
      indexName: "echoxu",
      pathsToMatch: ["https://www.echoxu.cn/**"],
      recordExtractor: ({ helpers }) => {
        return helpers.docsearch({
          recordProps: {
            lvl0: {
              selectors: ".sidebar-heading.collapsible",
              defaultValue: "Documentation",
            },
            lvl1: ["head > title", ".theme-default-content div h1"],
            lvl2: ".theme-default-content div h2",
            lvl3: ".theme-default-content div h3",
            lvl4: ".theme-default-content div h4",
            lvl5: ".theme-default-content div h5",
            lvl6: ".theme-default-content div h6",
            content:
              ".theme-default-content div p, .theme-default-content div ul li, .theme-default-content ul li a",
            lang: "",
            tags: {
              defaultValue: ["v1"],
            },
          },
          indexHeadings: true,
          aggregateContent: true,
          recordVersion: "v3",
        });
      },
    },
  ],
  initialIndexSettings: {
    echoxu: {
      attributesForFaceting: ["type", "lang", "language", "version"],
      attributesToRetrieve: [
        "hierarchy",
        "content",
        "anchor",
        "url",
        "url_without_anchor",
        "type",
      ],
      attributesToHighlight: ["hierarchy", "hierarchy_camel", "content"],
      attributesToSnippet: ["content:10"],
      camelCaseAttributes: ["hierarchy", "hierarchy_radio", "content"],
      searchableAttributes: [
        "unordered(hierarchy_radio_camel.lvl0)",
        "unordered(hierarchy_radio.lvl0)",
        "unordered(hierarchy_radio_camel.lvl1)",
        "unordered(hierarchy_radio.lvl1)",
        "unordered(hierarchy_radio_camel.lvl2)",
        "unordered(hierarchy_radio.lvl2)",
        "unordered(hierarchy_radio_camel.lvl3)",
        "unordered(hierarchy_radio.lvl3)",
        "unordered(hierarchy_radio_camel.lvl4)",
        "unordered(hierarchy_radio.lvl4)",
        "unordered(hierarchy_radio_camel.lvl5)",
        "unordered(hierarchy_radio.lvl5)",
        "unordered(hierarchy_radio_camel.lvl6)",
        "unordered(hierarchy_radio.lvl6)",
        "unordered(hierarchy_camel.lvl0)",
        "unordered(hierarchy.lvl0)",
        "unordered(hierarchy_camel.lvl1)",
        "unordered(hierarchy.lvl1)",
        "unordered(hierarchy_camel.lvl2)",
        "unordered(hierarchy.lvl2)",
        "unordered(hierarchy_camel.lvl3)",
        "unordered(hierarchy.lvl3)",
        "unordered(hierarchy_camel.lvl4)",
        "unordered(hierarchy.lvl4)",
        "unordered(hierarchy_camel.lvl5)",
        "unordered(hierarchy.lvl5)",
        "unordered(hierarchy_camel.lvl6)",
        "unordered(hierarchy.lvl6)",
        "content",
      ],
      distinct: true,
      attributeForDistinct: "url",
      customRanking: [
        "desc(weight.pageRank)",
        "desc(weight.level)",
        "asc(weight.position)",
      ],
      ranking: [
        "words",
        "filters",
        "typo",
        "attribute",
        "proximity",
        "exact",
        "custom",
      ],
      highlightPreTag: '<span class="algolia-docsearch-suggestion--highlight">',
      highlightPostTag: "</span>",
      minWordSizefor1Typo: 3,
      minWordSizefor2Typos: 7,
      allowTyposOnNumericTokens: false,
      minProximity: 1,
      ignorePlurals: true,
      advancedSyntax: true,
      attributeCriteriaComputedByMinProximity: true,
      removeWordsIfNoResults: "allOptional",
    },
  },
  appId: "你的 appid",
  apiKey: "你的 apikey",
});


algolia 管理后台操作指南

  • 重新生成记录:去 algolia 管理后台 选择「Overview」,然后点击右上角的「Restart crawling」
  • 测试索引是否生成:登录 「algolia 管理后台」点击「Editor」,选择「URL Tester」, 然后输入你要测试的文章 url ,最后点击「Run Test」
  • 查看生成的索引:登录 「algolia 管理后台」点击「Monitoring」可查看到我们生成的索引。


vuepress 中使用 algolia

  • 安装插件:yarn add -D @vuepress/plugin-docsearch@2.0.0-beta.46
  • 启用插件:config/pluginConf.js 中添加如下
点击查看 pluginConf.js
docsearchPlugin({
    apiKey: 'your apikey', // 从 DocSearch 团队收到的 apiKey
    appId: 'your appid',
    indexName: 'echoxu',
    locales: {
    '/': {
        placeholder: '搜索文档',
        translations: {
        button: {
            buttonText: '搜索文档',
        },
        },
    },
    '/zh/': {
        placeholder: '搜索文档',
        translations: {
        button: {
            buttonText: '搜索文档',
        },
        },
    },
    },
}),
  • 配置 vuepress 使 algolia search 生效,此代码由 algolia 邮件提供,在 config/headConf.js 中添加以下代码:
['link', { rel: 'stylesheet', type: 'text/css', href: 'https://cdn.jsdelivr.net/npm/@docsearch/css@3' }],
['script', { src: "https://cdn.jsdelivr.net/npm/@docsearch/js@3" }]
  • 创建 .vuepress/enhanceApp.js 文件并添加:
点击查看 enhanceApp.js
export default ({ router, Vue, isServer }) => {
  Vue.mixin({
  mounted() {
      // 不加 setTimeout 会有报错,但不影响效果
      setTimeout(() => {
      try {
          docsearch({
          appId: "your appid",
          apiKey: "your apikey",
          indexName: "echoxu",
          container: '.docsearch-container', // 这是 vuepress2 的容器
          debug: false
          });
      } catch(e) {
          console.log(e);
      }
      }, 100)
  },
  });
};


FAQ

algolia 后台查看到的记录数为 0?
  • 描述:登录 algolia 管理后台 点击 "Overview---Indices---Records" 发现记录数是 0
  • 原因:因为默认的 algolia 生成的配置有问题,无法匹配 vuepress2
  • 解决办法:登录 algolia 管理后台 点击 "Editor",修改如下内容:
    • discoveryPatterns: ["https://www.echoxu.cn/docs/**"], 改为 https://www.echoxu.cn/**
    • 删除所有的 .content__default 因为 vuepress2 没有这个 class
我的文章链接没有被爬取?
  • 原因:algolia 默认只爬取菜单栏的 url,我们可去管理后台手动添加要爬取的链接, 登录 algolia 管理后台 然后选择 "Tools---URL Inspector---Crawl a URL",然后填写我们文章的链接,它会自动爬取,当然这会很麻烦,可考虑自建 algolia 服务器
  • 解决办法:安装 vuepress-plugin-sitemap2 插件:yarn add -D vuepress-plugin-sitemap2
  • config/pluginConfig.js 中添加
    const { sitemapPlugin } = require("vuepress-plugin-sitemap2");
    sitemapPlugin({
      hostname: 'https://www.echoxu.cn',
    }),
    
  • 执行 yarn docs:build 会在 .vuepress/dist 中生成 sitemap.xml 文件
  • 如果是手动编写的 sitemap.xml 需要放在 .vuepress/public 目录中,然后执行 yarn docs:build 会将此文件复制到 .vuepress/dist 中。
  • 在线生成 sitemap 的工具:
每次更新文章后都要更新 algolia 索引记录?
  • 可考虑用 github action 来解决
  • 每次添加了一篇笔记后就在 sitemap.xml 里添加一条记录,然后将 sitemap.xml 提交到网站根目录,由于 robots.txt 的位置是固定的,可将 sitemap 的位置信息放在 robots.txt 里,sitemap 人工维护不太靠谱,google 提供了工具可以自动生成 sitemap。


参考

上次更新:
贡献者: iEchoxu