更多干货
分布式实战 (干货)
spring cloud 实战 (干货)
mybatis 实战 (干货)
spring boot 实战 (干货)
React 入门实战 (干货)
构建中小型互联网企业架构 (干货)
python 学习持续更新
1 根据用户 ID 是否隐藏帖子 ID 发帖日期来搜索帖子
1) 插入一些测试帖子数据
- POST /forum/article/_bulk
- { "index": { "_id": 1 }}
- { "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
- { "index": { "_id": 2 }}
- { "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
- { "index": { "_id": 3 }}
- { "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
- { "index": { "_id": 4 }}
- { "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }
初步来说, 就先搞 4 个字段, 因为整个 es 是支持 json document 格式的, 所以说扩展性和灵活性非常之好如果后续随着业务需求的增加, 要在 document 中增加更多的 field, 那么我们可以很方便的随时添加 field
但是如果是在关系型数据库中, 比如 mysql, 我们建立了一个表, 现在要给表中新增一些 column, 那就很坑爹了, 必须用复杂的修改表结构的语法去执行而且可能对系统代码还有一定的影响
- GET /forum/_mapping/article
- {
- "forum": {
- "mappings": {
- "article": {
- "properties": {
- "articleID": {
- "type": "text",
- "fields": {
- "keyword": {
- "type": "keyword",
- "ignore_above": 256
- }
- }
- },
- "hidden": {
- "type": "boolean"
- },
- "postDate": {
- "type": "date"
- },
- "userID": {
- "type": "long"
- }
- }
- }
- }
- }
- }
现在 es 5.2 版本, type=text, 默认会设置两个 field, 一个是 field 本身, 比如 articleID, 就是分词的; 还有一个的话, 就是 field.keyword,articleID.keyword, 默认不分词, 会最多保留 256 个字符
2) 根据用户 ID 搜索帖子
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "userID" : 1
- }
- }
- }
- }
- }
term filter/query: 对搜索文本不分词, 直接拿去倒排索引中匹配, 你输入的是什么, 就去匹配什么
比如说, 如果对搜索文本进行分词的话, helle world --> hello 和 world, 两个词分别去倒排索引中匹配
term,hello world --> hello world, 直接去倒排索引中匹配 hello world
3) 搜索没有隐藏的帖子
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "hidden" : false
- }
- }
- }
- }
- }
4) 根据发帖日期搜索帖子
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "postDate" : "2017-01-01"
- }
- }
- }
- }
- }
5) 根据帖子 ID 搜索帖子
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "articleID" : "XHDK-A-1293-#fJ3"
- }
- }
- }
- }
- }
- {
- "took": 1,
- "timed_out": false,
- "_shards": {
- "total": 5,
- "successful": 5,
- "failed": 0
- },
- "hits": {
- "total": 0,
- "max_score": null,
- "hits": []
- }
- }
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "articleID.keyword" : "XHDK-A-1293-#fJ3"
- }
- }
- }
- }
- }
- {
- "took": 2,
- "timed_out": false,
- "_shards": {
- "total": 5,
- "successful": 5,
- "failed": 0
- },
- "hits": {
- "total": 1,
- "max_score": 1,
- "hits": [
- {
- "_index": "forum",
- "_type": "article",
- "_id": "1",
- "_score": 1,
- "_source": {
- "articleID": "XHDK-A-1293-#fJ3",
- "userID": 1,
- "hidden": false,
- "postDate": "2017-01-01"
- }
- }
- ]
- }
- }
articleID.keyword, 是 es 最新版本内置建立的 field, 就是不分词的
所以一个 articleID 过来的时候, 会建立两次索引, 一次是自己本身, 是要分词的, 分词后放入倒排索引;
另外一次是基于 articleID.keyword, 不分词, 保留 256 个字符最多, 直接一个字符串放入倒排索引中
所以 term filter, 对 text 过滤, 可以考虑使用内置的 field.keyword 来进行匹配
但是有个问题, 默认就保留 256 个字符所以尽可能还是自己去手动建立索引, 指定 not_analyzed 吧在最新版本的 es 中, 不需要指定 not_analyzed 也可以, 将 type=keyword 即可
6) 查看分词
- GET /forum/_analyze
- {
- "field": "articleID",
- "text": "XHDK-A-1293-#fJ3"
- }
默认是 analyzed 的 text 类型的 field, 建立倒排索引的时候, 就会对所有的 articleID 分词, 分词以后, 原本的 articleID 就没有了, 只有分词后的各个 word 存在于倒排索引中
term, 是不对搜索文本分词的, XHDK-A-1293-#fJ3 --> XHDK-A-1293-#fJ3; 但是 articleID 建立索引的时候, XHDK-A-1293-#fJ3 --> xhdk,a,1293,fj3
7) 重建索引
- DELETE /forum
- PUT /forum
- {
- "mappings": {
- "article": {
- "properties": {
- "articleID": {
- "type": "keyword"
- }
- }
- }
- }
- }
- POST /forum/article/_bulk
- { "index": { "_id": 1 }}
- { "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
- { "index": { "_id": 2 }}
- { "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
- { "index": { "_id": 3 }}
- { "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
- { "index": { "_id": 4 }}
- { "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }
8) 重新根据帖子 ID 和发帖日期进行搜索
- GET /forum/article/_search
- {
- "query" : {
- "constant_score" : {
- "filter" : {
- "term" : {
- "articleID" : "XHDK-A-1293-#fJ3"
- }
- }
- }
- }
- }
2 知识点
(1)term filter: 根据 exact value 进行搜索, 数字 booleandate 天然支持
(2)text 需要建索引时指定为 not_analyzed, 才能用 term query
(3) 相当于 SQL 中的单个 where 条件
- select *
- from forum.article
- where articleID='XHDK-A-1293-#fJ3'
来源: http://blog.csdn.net/qq_27384769/article/details/79620105