【问题标题】:How do I build Lunr search for Markdown MD Documents如何构建 Lunr 搜索 Markdown MD 文档
【发布时间】:2021-09-09 20:44:44
【问题描述】:

我需要在我的站点上的 MD (Markdown) 文档中添加一个好的 lunr 搜索。我正在使用 React/NextJS 站点,我们在博客和常规“文档”区域都有很多 Markdown 文档。我们需要搜索这些文档,以便网站用户可以搜索主题。 MD 通过 NextJS 实时呈现,一切都很好,但我们需要添加服务器端搜索。出于安全原因,我们必须将用户 UI 限制为仅接收结果,而不是让页面仅搜索客户端/浏览器端。我们还需要在服务器端进行搜索,并且永远不要超出我们的 Intranet,因为这是企业防火墙的情况,并且网站无法使用外部 Internet 上的链接。无论如何,这是场景:

  • 在网站构建时构建 lunr 搜索索引(它都是静态的,所以这并不难)
  • 使用 API 端点路由对搜索索引进行服务器端搜索。
  • 使用 nextJS 客户端作为访问 API 端点以进行搜索和结果的用户交互点。

我知道如何使用 lunr、构建索引、构建 API 路由器端点并呈现到屏幕/页面。但我需要做的是了解如何构建索引和搜索 MD 文档的渲染版本(我猜这将显示为 HTML)。如何为 lunr 索引构建提供以下内容:a) 没有 MD 不可搜索的元信息,或 b) HTML 不可搜索的 HTML 标记。你看到问题了吗?我需要针对用户想要搜索的真实文本构建索引,而不是 Markdown 或 HTML 中的语言标签。是否已经有一个 NPM 包可以做这种事情?

我也想知道如何分解可搜索索引,以使搜索结果看起来不错,并带有一些预览,包括每个匹配项的句子,而不仅仅是页面名称..

【问题讨论】:

    标签: javascript search next.js markdown lunrjs


    【解决方案1】:

    您可以通过搜索两次来做到这一点。

    1. 从后端获取页面并通过 api 公开。
    2. 在 UI 中,您可以再次进行搜索并突出显示必要的字词。

    Here 适合你。

    我使用“react-highlight-words”库来简化。

    代码:

    进口

    <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-highlight-words@0.17.0/dist/main.min.js"></script>
    

    实际逻辑

    import React, { useState, useEffect, Component } from 'react';
    import { render } from 'react-dom';
    import Highlighter from 'react-highlight-words';
    
    const App = () => {
      const [text, setText] = useState('');
      const [data, setData] = useState('');
      const HINT = 'Search any name';
    
      const searchName = async text => {
        const URI = `https://api.nationalize.io/?name=${text}`;
        return fetch(URI);
      };
    
      useEffect(() => {
        (async () => {
          if (!text) {
            setData(HINT);
            return;
          }
    
          const res = await searchName(text);
          const data = await res.text();
          setData(data);
        })();
      }, [text]);
    
      return (
        <div>
          <input value={text} onChange={e => setText(e.target.value)} />
          <br />
          <br />
    
          <Highlighter searchWords={[text]} textToHighlight={data} />
        </div>
      );
    };
    
    render(<App />, document.getElementById('root'));
    

    【讨论】:

    • 感谢 Shravan 的快速回复。不幸的是,我原来的问题帖子有两个错误,可能以错误的方式暗示了这个问题。首先,我对使用外部搜索提出了双重否定。整个网站必须留在内网,不能外网。另外,我应该说明我的请求的原因。您上面的示例可以访问互联网,在我的情况下我无法使用。 (尽管它可能对没有这种限制的人有所帮助)。我已将问题更新为更准确。
    • 知道了@KimGentes。我想那我们可能无法接受我的回答。
    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2011-05-26
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多