document id的手动指定与自动生成两种方式解析

课程大纲

1、手动指定document id
2、自动生成document id


1、手动指定document id

(1)根据应用情况来说,是否满足手动指定document id的前提:

一般来说,是从某些其他的系统中,导入一些数据到es时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为es中document的id。举个例子,比如说,我们现在在开发一个电商网站,做搜索功能,或者是OA系统,做员工检索功能。这个时候,数据首先会在网站系统或者IT系统内部的数据库中,会先有一份,此时就肯定会有一个数据库的primary key(自增长,UUID,或者是业务编号)。如果将数据导入到es中,此时就比较适合采用数据在数据库中已有的primary key。

如果说,我们是在做一个系统,这个系统主要的数据存储就是es一种,也就是说,数据产生出来以后,可能就没有id,直接就放es一个存储,那么这个时候,可能就不太适合说手动指定document id的形式了,因为你也不知道id应该是什么,此时可以采取下面要讲解的让es自动生成id的方式。

(2)put /index/type/id

PUT /test_index/test_type/2
{
“test_content”: “my test”
}

2、自动生成document id

(1)post /index/type

POST /test_index/test_type
{
“test_content”: “my test”
}

{
“_index”: “test_index”,
“_type”: “test_type”,
“_id”: “AVp4RN0bhjxldOOnBxaE”,
“_version”: 1,
“result”: “created”,
“_shards”: {
“total”: 2,
“successful”: 1,
“failed”: 0
},
“created”: true
}

(2)自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突
在这里插入图片描述

课程大纲

1、_source元数据

put /test_index/test_type/1
{
“test_field1”: “test field1”,
“test_field2”: “test field2”
}

get /test_index/test_type/1

{
“_index”: “test_index”,
“_type”: “test_type”,
“_id”: “1”,
“_version”: 2,
“found”: true,
“_source”: {
“test_field1”: “test field1”,
“test_field2”: “test field2”
}
}

_source元数据:就是说,我们在创建一个document的时候,使用的那个放在request body中的json串,默认情况下,在get的时候,会原封不动的给我们返回回来。


2、定制返回结果

定制返回的结果,指定_source中,返回哪些field

GET /test_index/test_type/1?_source=test_field1,test_field2

{
“_index”: “test_index”,
“_type”: “test_type”,
“_id”: “1”,
“_version”: 2,
“found”: true,
“_source”: {
“test_field2”: “test field2”
}
}

课程大纲

1、document的全量替换
2、document的强制创建
3、document的删除


1、document的全量替换

(1)语法与创建文档是一样的,如果document id不存在,那么就是创建;如果document id已经存在,那么就是全量替换操作,替换document的json串内容
(2)document是不可变的,如果要修改document的内容,第一种方式就是全量替换,直接对document重新建立索引,替换里面所有的内容
(3)es会将老的document标记为deleted,然后新增我们给定的一个document,当我们创建越来越多的document的时候,es会在适当的时机在后台自动删除标记为deleted的document


2、document的强制创建

(1)创建文档与全量替换的语法是一样的,有时我们只是想新建文档,不想替换文档,如果强制进行创建呢?
(2)PUT /index/type/id?op_type=create,PUT /index/type/id/_create


3、document的删除

(1)DELETE /index/type/id
(2)不会理解物理删除,只会将其标记为deleted,当数据越来越多的时候,在后台自动删除.

在这里插入图片描述

<think>好的,我现在需要帮助用户解决如何在Markdown中自动生成多级目录的问题。首先,我得仔细看看用户的问题和之前的对话历史,确保我理解他的需求。用户之前问过关于CSDN专栏是否支持多级分类,现在他想知道如何在Markdown中自动生成多级目录。根据之前的回答,我提到了通过标签和目录模拟的方法,但用户现在希望更具体的自动生成方法。 用户提供了三个引用,我需要参考这些内容。引用[1]提到在Vue2/Nuxt2项目中解析Markdown内容,自动生成多级目录,并支持点击跳转和高亮效果。引用[2]讨论了R Markdown中使用captioner包实现图表交叉引用,虽然不直接相关,但可能对编号有帮助。引用[3]展示了一个手动创建目录的例子,使用锚点链接。 用户的主要需求是自动生成多级目录,而不是手动创建。因此,我需要结合这些引用,特别是引用[1]和[3],来给出解决方案。首先,自动生成目录通常需要解析Markdown中的标题(如#、##等),然后生成对应的链接。手动方法虽然可行,但效率低,容易出错,所以用户需要自动化工具或插件。 接下来,我需要考虑不同的实现环境。例如,在静态网站生成器(如VuePress、Docsify)中,可能有内置的目录生成功能。或者在本地使用脚本或工具(如Pandoc)来处理Markdown文件,自动提取标题并生成目录。此外,引用[1]中的Vue项目示例说明可以通过前端代码解析Markdown内容,动态生成目录树,这可能需要编写自定义的JavaScript代码来识别标题标签并构建目录结构。 同时,用户可能需要知道如何在不同平台(如CSDN)实现自动目录,但根据之前的回答,CSDN本身不支持多级分类,但可以通过标签和目录模拟。然而,自动生成目录可能需要特定的Markdown解析器或扩展支持。 可能的步骤包括:使用工具或库解析Markdown,提取标题及其层级,生成带缩进的列表,并正确设置锚点链接。此外,还需要考虑目录的样式和交互功能,如高亮当前阅读位置,这可能需要额外的JavaScript代码或CSS样式。 需要提醒用户注意不同平台对Markdown的支持程度,某些平台可能不支持自动生成目录,需要依赖外部工具或手动维护。同时,提供具体的代码示例或工具推荐会更有帮助,比如使用markdown-it插件在Vue项目中生成目录,或者使用Python脚本处理Markdown文件。 最后,确保回答结构清晰,分点说明不同方法,并比较它们的优缺点,帮助用户根据具体需求选择合适的方法。还要注意用户可能需要解决生成目录时的常见问题,如锚点链接的正确格式、标题层级的嵌套是否正确等,这些都需要在回答中提及。</think>根据技术实现方式和应用场景,在Markdown中自动生成多级目录主要有以下两种主流方法,结合引用内容给出具体方案: --- ### 一、**静态生成方案**(适用于本地/静态网站) #### 1. **工具链集成** 通过`Pandoc`或`Markdown解析库`自动提取标题层级,示例代码: ```bash # 使用Pandoc生成带目录的HTML(自动识别#~######标题) pandoc input.md --toc -o output.html ``` *生成效果:标题层级转换为`<ul><li>`嵌套列表,支持6级目录[^1]* #### 2. **脚本自动化** Python示例(使用`markdown`库提取标题): ```python import markdown from markdown.treeprocessors import Treeprocessor class TocGenerator(Treeprocessor): def run(self, root): toc = [] for element in root.iter('h1', 'h2', 'h3', 'h4', 'h5', 'h6'): level = int(element.tag[1]) text = element.text anchor = text.lower().replace(' ', '-') toc.append(f'{" "*(level-1)}* [{text}](#{anchor})') return '\n'.join(toc) md = markdown.Markdown(extensions=['toc']) md.treeprocessors.register(TocGenerator(), 'toc_gen', 15) print(md.convert(open('input.md').read())) ``` *输出结果示例:* ``` * [一级标题](#一级标题) * [二级标题](#二级标题) * [三级标题](#三级标题) ``` --- ### 二、**动态生成方案**(适用于Web项目) #### 1. **前端框架集成** 参考引用[1]的Vue实现逻辑: ```javascript // 在Vue组件中解析Markdown内容 methods: { generateToc(mdContent) { const headings = mdContent.match(/^#{1,6} .+/gm) || []; return headings.map(heading => { const level = heading.match(/^#+/)[0].length; const title = heading.replace(/^#+ /, ''); const anchor = title.toLowerCase().replace(/\s+/g, '-'); return { level, title, anchor: `#${anchor}` }; }); } } ``` *渲染效果:动态生成带缩进层级的导航菜单,点击跳转并高亮[^1]* #### 2. **浏览器端实时解析** 使用`marked.js`库实现(需引入DOM操作): ```html <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <div id="toc"></div> <div id="content"></div> <script> const mdContent = `# 标题1\n## 标题2\n### 标题3`; const parsedHTML = marked.parse(mdContent); document.getElementById('content').innerHTML = parsedHTML; // 生成目录 const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6')); const toc = headings.map(h => { const indent = ' '.repeat(parseInt(h.tagName[1]) - 1); return `${indent}* [${h.textContent}](#${h.id})`; }).join('\n'); document.getElementById('toc').innerHTML = marked.parse(toc); </script> ``` --- ### 三、**平台兼容性对比** | 方案 | CSDN/GitHub | VuePress/Docsify | 独立网站 | |--------------------|-------------|------------------|----------| | 静态生成 | 需手动粘贴 | ✅ 原生支持 | ✅ | | 动态生成(前端) | ❌ | ✅ 需插件扩展 | ✅ | | 脚本预处理 | ✅ 导出后上传 | ✅ 构建时生成 | ✅ | --- ### 四、**关键问题解决** 1. **锚点重复冲突** 添加唯一标识符(如`-1`后缀): ```javascript function generateAnchor(title, existingAnchors) { let base = title.toLowerCase().replace(/\s+/g, '-'); let anchor = base; let count = 1; while (existingAnchors.has(anchor)) { anchor = `${base}-${count++}`; } return anchor; } ``` 2. **滚动高亮同步** 监听滚动事件实现目录联动: ```javascript window.addEventListener('scroll', () => { const headings = document.querySelectorAll('h1, h2, h3'); let currentActive = null; headings.forEach(heading => { if (heading.offsetTop <= window.scrollY + 100) { currentActive = heading.id; } }); document.querySelectorAll('.toc a').forEach(a => { a.classList.toggle('active', a.getAttribute('href') === `#${currentActive}`); }); }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值