十四 搜索相关知识点(multi-search、分页搜索、deep paging、query string、_all metadata、mapping、exact value/full text)

1. 常见的搜索模式有如下形式:

/_search:所有索引,所有type下的所有数据都搜索出来
/index1/_search:指定一个index,搜索其下所有type的数据
/index1,index2/_search:同时搜索两个index下的数据
/*1,*2/_search:按照通配符去匹 配多个索引
/index1/type1/_search:搜索一个index下指定的type的数据
/index1/type1,type2/_search:可以搜索一个index下多个type的数据
/index1,index2/type1,type2/_search:搜索多个index下的多个type的数据
/_all/type1,type2/_search:_all,可以代表搜索所有index下的指定type的数据

 

因为每个shard都只是包含部分数据,所以client搜索请求会发到对应的所有primary shard和replica shard上去。

2. 分页搜索

size(搜索大小),from(起始位置)

GET /_search?size=10
GET /_search?size=10&from=0
GET /_search?size=10&from=20

3. deep paging问题

当要搜索的数据特别多,也就是搜索的特别深。

比如数据量有90000条,3个shard,每个shard上分了30000条,每页10条数据,这个时候搜到1000页的话,客户端实际想要拿到的数据是10001~10010这10条数据。在搜索的时候,对于每个shard,他们要返回的数据并不是10条数据,而是10010条数据,也就是每个shard都要返回10010条数据给coordinate node,那么coordinate node总共接收到30030条数据,然后根据_score相关度排序,最后取到排位最高的10条数据返回给client。

这样就导致,coordinate node上保存大量的数据,还要进行大量数据的排序,排序后在取出对应的那一页,这就会耗费内存,网络带款和CPU,产生性能问题,所以要尽量避免出现这种操作。

4. query string基础语法

GET /test_index/test_type/_search?q=test_field:test  //搜索所有含有test的内容
GET /test_index/test_type/_search?q=+test_field:test  //必须含有test,作用与第一条是一样的
GET /test_index/test_type/_search?q=-test_field:test   //不能含有test

5. _all metadata
直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。我们在进行中搜索的时候,难道是对document中的每一个field都进行一次搜索吗?不是的

es中的_all元数据,在建立索引的时候,我们插入一条document,它里面包含了多个field,此时,es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引

后面如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field,其中是包含了所有field的值的

举个例子

{
  "name": "jack",
  "age": 26,
  "email": "jack@sina.com",
  "address": "guamgzhou"
}

"jack 26 jack@sina.com guangzhou",作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引

6. mapping

创建document的时候,默认ES会自动建立mapping,不同的field设置为不同的data type,不同的data type的分词、搜索行为是不一样的,这会影响关键字的搜索结果。一个mapping的形式如下:

GET /website/_mapping/article

{
  "website": {
    "mappings": {
      "article": {
        "properties": {
          "author_id": {
            "type": "long"
          },
          "content": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "post_date": {
            "type": "date"
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

mapping也可以手动建立,没有手动建立的话,ES自动建立的mapping称为dynamic mapping。

7. 搜索模式

精确搜索(exact value):

完全按搜索字符串匹配,多了字符或少了字符都不能搜索到。

全文搜索(full text):

以下情况都可以搜索到

(1)缩写 vs. 全程:cn vs. china
(2)格式转化:like liked likes
(3)大小写:Tom vs tom
(4)同义词:like vs love

2017-01-01,2017 01 01,搜索2017,或者01,都可以搜索出来
china,搜索cn,也可以将china搜索出来
likes,搜索like,也可以将likes搜索出来
Tom,搜索tom,也可以将Tom搜索出来
like,搜索love,同义词,也可以将like搜索出来

就不是说单纯的只是匹配完整的一个值,而是可以对值进行拆分词语后(分词)进行匹配,也可以通过缩写、时态、大小写、同义词等进行匹配。

8. mapping搜索案例

插入如下3条数据:

PUT /website/article/1
{
  "post_date": "2017-01-01",
  "title": "my first article",
  "content": "this is my first article in this website",
  "author_id": 11400
}

PUT /website/article/2
{
  "post_date": "2017-01-02",
  "title": "my second article",
  "content": "this is my second article in this website",
  "author_id": 11400
}

PUT /website/article/3
{
  "post_date": "2017-01-03",
  "title": "my third article",
  "content": "this is my third article in this website",
  "author_id": 11400
}

尝试各种搜索

GET /website/article/_search?q=2017            3条结果:这是一个全文搜索,上面3条数据进行分词器处理后,都含有2017,因此都可以被搜索到。
GET /website/article/_search?q=2017-01-01            3条结果:这也是一个全文搜索,上面3条数据进行分词器处理后,都含有2017,并且搜索字符串也要经过分词器处理,含有2017,故3条数据也都可以被搜索到。
GET /website/article/_search?q=post_date:2017-01-01       1条结果:这是一个精确搜索,只有含有2017-01-01的记录才能被搜索到。
GET /website/article/_search?q=post_date:2017             1条结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
uint64_t S1mmeSession::UpdateUserDataSTMSIChange(S1APNode* p_node, uint64_t stmsi) { if(!stmsi) return 0; uint64_t old_stmsi = 0; //如果stmsi没有改变, 则直接返回 SPUserInfo& sp_local_user_info = p_node->GetUserInfo(); if (sp_local_user_info->HasSTMSI() && sp_local_user_info->GetSTMSI() == stmsi) { return old_stmsi; } //删除 old stmsi if (sp_local_user_info->HasSTMSI()) { old_stmsi = sp_local_user_info->GetSTMSI(); STMSI_Iter iter = ue_stmsi_map_.find(old_stmsi); if (iter != ue_stmsi_map_.end()) { ue_stmsi_map_.erase(iter); } DeleteFromStmsiTimeoutMap(old_stmsi); } //删除可能的 paging 干扰 StmsiWithMmegi_T old_stmsi_key(old_stmsi); S1APNode** pp_paging = p_stmsi_paging_map_->GetData(old_stmsi_key); if (pp_paging != NULL) { if (handle_session_version_ == S1MME_SESSION_VERSION_CHINA_TELECOM) { CtOutputNode(*pp_paging, false); } else { (*pp_paging)->DeletePagingKqi(); } p_stmsi_paging_map_->DeleteData(old_stmsi_key, p_s1ap_node_allocator_); } StmsiWithMmegi_T new_stmsi_key(stmsi); pp_paging = p_stmsi_paging_map_->GetData(new_stmsi_key); if (pp_paging != NULL) { if(handle_session_version_ == S1MME_SESSION_VERSION_CHINA_TELECOM) { CtOutputNode(*pp_paging, false); } else { (*pp_paging)->DeletePagingKqi(); } p_stmsi_paging_map_->DeleteData(new_stmsi_key, p_s1ap_node_allocator_); } //删除可能的 new_stmsi 干扰 STMSI_Iter iter = ue_stmsi_map_.find(stmsi); if (iter != ue_stmsi_map_.end()) { iter->second->flag_.stmsi = false; iter->second->index_.stmsi =0; ue_stmsi_map_.erase(iter); } UpdateFromStmsiTimeoutMap(stmsi, current_time_.tv_sec, true); //插入 new_stmsi(local user info) ue_stmsi_map_.insert(std::make_pair(stmsi, sp_local_user_info)); sp_local_user_info->SetSTMSI(stmsi); return old_stmsi; }什么意思
最新发布
06-11

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值