es表里怎么搜题最快
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es表里怎么搜题最快相关的知识,希望对你有一定的参考价值。
参考技术A 、前言最近接触的几个项目都使用到了 Elasticsearch (以下简称 ES ) 来存储数据和对数据进行搜索分析,就对 ES 进行了一些学习。本文整理自我自己的一次技术分享。
本文不会关注 ES 里面的分布式技术、相关 API 的使用,而是专注分享下 ”ES 如何快速检索“这个主题上面。这个也是我在学习之前对 ES 最感兴趣的部分。
本文大致包括以下内容:
关于搜索
传统关系型数据库和 ES 的差别
搜索引擎原理
细究倒排索引
倒排索引具体是个什么样子的(posting list -> term dic -> term index)
关于 postings list 的一些巧技 (FOR、Roaring Bitmaps)
如何快速做联合查询?
二、关于搜索
先设想一个关于搜索的场景,假设我们要搜索一首诗句内容中带“前”字的古诗,
用 传统关系型数据库和 ES 实现会有什么差别?
如果用像 MySQL 这样的 RDBMS 来存储古诗的话,我们应该会去使用这样的 SQL 去查询
selectnamefrom poems wherecontentlike"%前%";
这种我们称为顺序扫描法,需要遍历所有的记录进行匹配。
不但效率低,而且不符合我们搜索时的期望,比如我们在搜索“ABCD"这样的关键词时,通常还希望看到"A","AB","CD",“ABC”的搜索结果。
于是乎就有了专业的搜索引擎,比如我们今天的主角 -- ES。
搜索引擎原理
搜索引擎的搜索原理简单概括的话可以分为这么几步,
内容爬取,停顿词过滤比如一些无用的像"的",“了”之类的语气词/连接词
内容分词,提取关键词
根据关键词建立倒排索引
用户输入关键词进行搜索
这里我们就引出了一个概念,也是我们今天的要剖析的重点 - 倒排索引。也是 ES 的核心知识点。
如果你了解 ES 应该知道,ES 可以说是对 Lucene 的一个封装,里面关于倒排索引的实现就是通过 lucene 这个 jar 包提供的 API 实现的,所以下面讲的关于倒排索引的内容实际上都是 lucene 里面的内容。
三、倒排索引
首先我们还不能忘了我们之前提的搜索需求,先看下建立倒排索引之后,我们上述的查询需求会变成什么样子,
这样我们一输入“前”,借助倒排索引就可以直接定位到符合查询条件的古诗。
当然这只是一个很大白话的形式来描述倒排索引的简要工作原理。在 ES 中,这个倒排索引是具体是个什么样的,怎么存储的等等,这些才是倒排索引的精华内容。
1. 几个概念
在进入下文之前,先描述几个前置概念。
term
关键词这个东西是我自己的讲法,在 ES 中,关键词被称为 term。
postings list
还是用上面的例子,
静夜思, 望庐山瀑布
是 "前" 这个 term 所对应列表。在 ES 中,这些被描述为所有包含特定 term 文档的 id 的集合。由于整型数字 integer 可以被高效压缩的特质,integer 是最适合放在 postings list 作为文档的唯一标识的,ES 会对这些存入的文档进行处理,转化成一个唯一的整型 id。
再说下这个 id 的范围,在存储数据的时候,在每一个 shard 里面,ES 会将数据存入不同的 segment,这是一个比 shard 更小的分片单位,这些 segment 会定期合并。在每一个 segment 里面都会保存最多 2^31 个文档,每个文档被分配一个唯一的 id,从0到(2^31)-1。
相关的名词都是 ES 官方文档给的描述,后面参考材料中都可以找到出处。
2. 索引内部结构
上面所描述的倒排索引,仅仅是一个很粗糙的模型。真的要在实际生产中使用,当然还差的很远。
在实际生产场景中,比如 ES 最常用的日志分析,日志内容进行分词之后,可以得到多少的 term?
那么如何快速的在海量 term 中查询到对应的 term 呢?遍历一遍显然是不现实的。
term dictionary
于是乎就有了 term dictionary,ES 为了能快速查找到 term,将所有的 term 排了一个序,二分法查找。是不是感觉有点眼熟,这不就是 MySQL 的索引方式的,直接用 B+树建立索引词典指向被索引的数据。
term index
但是问题又来了,你觉得 Term Dictionary 应该放在哪里?肯定是放在内存里面吧?磁盘 io 那么慢。就像 MySQL 索引就是存在内存里面了。
但是如果把整个 term dictionary 放在内存里面会有什么后果呢?
内存爆了...
别忘了,ES 默认可是会对全部 text 字段进行索引,必然会消耗巨大的内存,为此 ES 针对索引进行了深度的优化。在保证执行效率的同时,尽量缩减内存空间的占用。
于是乎就有了 term index。
Term index 从数据结构上分类算是一个“Trie 树”,也就是我们常说的字典树。这是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。
这棵树不会包含所有的 term,它包含的是 term 的一些前缀(这也是字典树的使用场景,公共前缀)。通过 term index 可以快速地定位到 term dictionary 的某个 offset,然后从这个位置再往后顺序查找。就想右边这个图所表示的。(怎么样,像不像我们查英文字典,我们定位 S 开头的第一个单词,或者定位到 Sh 开头的第一个单词,然后再往后顺序查询)
lucene 在这里还做了两点优化,一是 term dictionary 在磁盘上面是分 block 保存的,一个 block 内部利用公共前缀压缩, 参考技术B es表里怎么搜题最快:
1. 分布式讲究的合力解决问题。所以应该注意短板问题。
2. es 想要快,核心思想是减小搜索的集合,以及减少搜索命中的结果集,每个子查询都是关键点。
3. 非并发解决的问题, 参考技术C es表里怎么搜题最快。
首先在应用中心点击中间的全部功能,点击页面中间的拍照搜题,点页面下角的同一按钮,可以快速进行搜题操作。 请参考
怎么查找数据库所有表里面包含的某个文字
我现在有一个数据库
包含了很多的表
我现在想查找这所有的表里面包括XY1的表
怎么在整个数据库的所有表里查找啊
好多数据呢
一、可以使用数据库语言中的like语句进行查询。
二、数据库所有表里面包含的某个文字查询方法
1、在数据中,创建测试表、插入任意数据如下图
2、数据库中插入执行查找包含的某个文字语句,例如:要查找name列中含有“张”字体的语句段落:select * from test where name like \'***\',如下图
3、数据执行命令,结果如下图
参考技术Aselect name from sysobjects where xtype='u' and name like '%xy1%'
1. 后台添加扩展字段。
2. 选中所在的数据库右键新建查询并输入SQL 语句。
SELECT TABLE_NAME。
FROM INFORMATION_SCHEMA.COLUMNS。
WHERE COLUMN_NAME = 'abc123'。
参考技术B 你这个需求比较变态。要搜寻库中所有的表,而且XY1在哪个字段也不知道。即:要搜寻所有表的所有字段。
是oracle数据库吗?而且问题庞大分太少。飘过。。。。 参考技术C 看什么数据库了 oracle 的话
select * from all_tables where table_name like '%XY1%'追问
是SQL 2000
追答我对sqlserver不熟悉 应该是sysobjects表 你试试一楼的那个
参考技术D select name from sysobjects where xtype='u' and name like '%xy1%'追问是SQL数据库
您那个命令是吗
,,,,,
查询分析器里用了那个命令
提示完成
但是没有找到
是SQL2000数据库的命令,但我的语句只是列出某数据库所有由用户创建以及名字包涵“XY1”的表名,不知道是否是你要的结果。
如果像二楼所说的:
要搜寻库中所有的表,而且XY1在哪个字段也不知道。即:要搜寻所有表的所有字段。
这个要求确实是比较变态。但如果你达到这种要求估计也可以写出来
以上是关于es表里怎么搜题最快的主要内容,如果未能解决你的问题,请参考以下文章