61阅读

android搜索功能实现-Twitter推出姓名实时搜索 便于发现虚假名人

发布时间:2017-10-25 所属栏目:建站经验

一 : Twitter推出姓名实时搜索 便于发现虚假名人

  北京时间7月14日消息,据国外媒体报道,微博网站Twitter近日推出了姓名实时搜索功能,在搜索结果的突出位置显示姓名搜索结果。

  在此之前,Twitter搜索也提供姓名搜索结果,但此次Twitter专门在搜索结果最上方中心位置显示姓名搜索结果,而且位于常规实时搜索出现的Twitter信息之前。另外,搜索结果中的姓名也是水平排列,而普通搜索结果中的Twitter信息是垂直排列。

  这是Twitter添加的又一项新功能,并且有可能产生重大影响。例如,用户输入“勒布朗·詹姆斯”进行搜索,即可在搜索结果的最上方看到勒布朗·詹姆斯的个人Twitter账户,用户点击即可关注该账户。

  最近,Twitter还对数据进行了更新,以配合这项姓名搜索功能。这项姓名实时搜索功能还可以发现一些虚假的名人账户,Twitter在搜索结果中真正的名人Twitter账户后面添加了蓝色的标记,方便用户添加关注。

  业内人士认为,这项Twitter姓名搜索功能可以使名人的关注者大幅增加。

二 : 微信搜索现这么强大!微信内整体的搜索功能玩法介绍

微信现在已是v6.3.30 版本,但多少人知道,它在10 月28 日上线的v6.3.29 版本里已悄悄强化了微信内整体的搜索功能。

在“朋友圈”和“文章” 2 个搜索入口,微信针对性地增加了搜索条件选项:搜朋友圈的时候,可针对搜某个好友某类的朋友圈;搜文章的时候,则可以针对某个公众号搜某类文章,还可以设定时间条件。

软件名称:
微信 V6.3.1.8 for Android 官方中文免费 正式版
软件大小:
34.3MB
更新时间:
2016-06-02

软件名称:
微信 v6.2.2 官方ios版 苹果版
软件大小:
88.0MB
更新时间:
2015-06-17

新功能

小编和大家一起试用一下:

首先试试朋友圈搜索功能,我们来看下ifanr 硬件控在2016年对无人机的关注度如何?

搜索结果

噔!搜索结果出来,硬件控今年居然只转发了一篇无人机的文章,抓去角落检讨去。

搜索结果

然后我们试试公众号搜索功能。

既然我们今天在试玩微信搜索,就让我们看看之前还有什么关于微信搜索的文章吧。

微信搜索

噔!结果不仅搜出了爱范儿今年年初写了《微信搜索悄然升级,应用号初现端倪,3 大猜想……》,还在右下角透露了有多少个好友分享了!所以记得啦,如果下次让朋友帮转文章,记得事后搜搜,检查有多少人分享了。[机智地微笑]

搜索结果

一起来玩

机智地掌握搜索技巧后,欢迎各位一起在评论分享一下你的搜索体验。

友情建议:请各位自觉不要搜前男/女的朋友圈,然后还输入例如“开心”、“幸福”之类的关键词哦。

相关阅读:

手机微信怎么快速保获得微信公众号文章封面图?

微信收藏的视频该怎么发送到朋友圈?

微信怎么查看每天日出和日落时间?

三 : 详解美团实现搜索关键词自动匹配功能的方法

问题背景
搜索关键字智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,以提升用户搜索体验。

美团CRM系统中存在数以百万计的商家,为了让用户快速查找到目标商家,我们基于solrcloud实现了商家搜索模块。用户在查找商家时主要输入商户名、商户地址进行搜索,为了提升用户的搜索体验和输入效率,本文实现了一种基于solr前缀匹配查询关键字智能提示(Suggestion)实现。

需求分析
1.支持前缀匹配原则
在搜索框中输入“海底”,搜索框下面会以海底为前缀,展示“海底捞”、“海底捞火锅”、“海底世界”等等搜索词;输入“万达”,会提示“万达影城”、“万达广场”、“万达百货”等搜索词。
2.同时支持汉字、拼音输入
由于中文的特点,如果搜索自动提示可以支持拼音的话会给用户带来更大的方便,免得切换输入法。比如,输入“haidi”提示的关键字和输入“海底”提示的一样,输入“wanda”与输入“万达”提示的关键字一样。
3.支持多音字输入提示
比如输入“chongqing”或者“zhongqing”都能提示出“重庆火锅”、“重庆烤鱼”、“重庆小天鹅”。
4.支持拼音缩写输入
对于较长关键字,为了提高输入效率,有必要提供拼音缩写输入。比如输入“hd”应该能提示出“haidi”相似的关键字,输入“wd”也一样能提示出“万达”关键字。
基于用户的历史搜索行为,按照关键字热度进行排序
为了提供suggest关键字的准确度,最终查询结果,根据用户查询关键字的频率进行排序,如输入[重庆,chongqing,cq,zhongqing,zq] —> [“重庆火锅”(f1),“重庆烤鱼”(f2),“重庆小天鹅”(f3),…],查询频率f1 > f2 > f3。


解决方案
1.关键字收集
当用户输入一个前缀时,碰到提示的候选词很多的时候,如何取舍,哪些展示在前面,哪些展示在后面?这就是一个搜索热度的问题。用户在使用搜索引擎查找商家时,会输入大量的关键字,每一次输入就是对关键字的一次投票,那么关键字被输入的次数越多,它对应的查询就比较热门,所以需要把查询的关键字记录下来,并且统计出每个关键字的频率,方便提示结果按照频率排序。搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。
2.汉字转拼音
用户输入的关键字可能是汉字、数字,英文,拼音,特殊字符等等,由于需要实现拼音提示,我们需要把汉字转换成拼音,java中考虑使用pinyin4j组件实现转换。
3.拼音缩写提取
考虑到需要支持拼音缩写,汉字转换拼音的过程中,顺便提取出拼音缩写,如“chongqing”,"zhongqing"--->"cq",”zq”。
4.多音字全排列
要支持多音字提示,对查询串转换成拼音后,需要实现一个全排列组合,字符串多音字全排列算法如下:

Java Code复制内容到剪贴板

  1. public static List getPermutationSentence(List> termArrays,int start) {   
  2.   
  3.   if (CollectionUtils.isEmpty(termArrays))   
  4.       return Collections.emptyList();   
  5.   
  6.   int size = termArrays.size();   
  7.   if (start < 0 || start >= size) {   
  8.       return Collections.emptyList();   
  9.   }   
  10.   
  11.   if (start == size-1) {   
  12.       return termArrays.get(start);   
  13.   }   
  14.   
  15.   List<String> strings = termArrays.get(start);   
  16.   
  17.   List<String> permutationSentences = getPermutationSentence(termArrays, start + 1);   
  18.   
  19.   if (CollectionUtils.isEmpty(strings)) {   
  20.       return permutationSentences;   
  21.   }   
  22.   
  23.   if (CollectionUtils.isEmpty(permutationSentences)) {   
  24.       return strings;   
  25.   }   
  26.   
  27.   List<String> result = new ArrayList<String>();   
  28.   for (String pre : strings) {   
  29.       for (String suffix : permutationSentences) {   
  30.           result.add(pre+suffix);   
  31.       }   
  32.   }   
  33.   
  34.   return result;   
  35. }  

索引与前缀查询
方案一 Trie树 + TopK算法
Trie树即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。Trie是一颗存储多个字符串的树。相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串。和普通树不同的地方是,相同的字符串前缀共享同一条分支。例如,给出一组单词inn, int, at, age, adv, ant, 我们可以得到下面的Trie:
2016331110317329.png (563×411)

从上图可知,当用户输入前缀i的时候,搜索框可能会展示以i为前缀的“in”,“inn”,”int"等关键词,再当用户输入前缀a的时候,搜索框里面可能会提示以a为前缀的“ate”等关键词。如此,实现搜索引擎智能提示suggestion的第一个步骤便清晰了,即用trie树存储大量字符串,当前缀固定时,存储相对来说比较热的后缀。

TopK算法用于解决统计热词的问题。解决TopK问题主要有两种策略:hashMap统计+排序、堆排序
hashmap统计: 先对这批海量数据预处理。具体方法是:维护一个Key为Query字串,Value为该Query出现次数的HashTable,即hash_map(Query,Value),每次读取一个Query,如果该字串不在Table中,那么加入该字串,并且将Value值设为1;如果该字串在Table中,那么将该字串的计数加一即可,最终在O(N)的时间复杂度内用Hash表完成了统计。
堆排序:借助堆这个数据结构,找出Top K,时间复杂度为N‘logK。即借助堆结构,我们可以在log量级的时间内查找和调整/移动。因此,维护一个K(该题目中是10)大小的小根堆,然后遍历300万的Query,分别和根元素进行对比。所以,我们最终的时间复杂度是:O(N) + N' * O(logK),(N为1000万,N’为300万)。

该方案存在的问题是:

建索引和查询的时候都要把汉字转换成拼音,查询完成后还得把拼音转换成汉字显示,且需要考虑数字和特殊字符。
需要维护拼音、缩写两棵Trie树。


方案二 Solr自带Suggest智能提示
Solr作为一个应用广泛的搜索引擎系统,它内置了智能提示功能,叫做Suggest模块。该模块可选择基于提示词文本做智能提示,还支持通过针对索引的某个字段建立索引词库做智能提示。 (详见solr的wiki页面http://wiki.apache.org/solr/Suggester)

该方案存在的问题是:

返回的结果是基于索引中字段的词频进行排序,不是用户搜索关键字的频率,因此不能将一些热门关键字排在前面。
拼音提示,多音字,缩写还是要另外加索引字段。


方案三 Solrcloud建立单独的collection,利用solr前缀查询实现
如前所述,以上两个方案在实施起来都存在一些问题,Trie树+TopK算法,在处理汉字suggest时不是很优雅,且需要维护两棵Trie树,实施起来比较复杂;Solr自带的suggest智能提示组件存在问题是使用freq排序算法,返回的结果完全基于索引中字符的出现次数,没有兼顾用户搜索词语的频率,因此无法将一些热门词排在更靠前的位置。于是,我们继续寻找一种解决这个问题更加优雅的方案。

至此,我们考虑专门为关键字建立一个索引collection,利用solr前缀查询实现。solr中的copyField能很好解决我们同时索引多个字段(汉字、pinyin, abbre)的需求,且field的multiValued属性设置为true时能解决同一个关键字的多音字组合问题。配置如下:

schema.xml:

XML/HTML Code复制内容到剪贴板

  1. <field name="kw" type="string" indexed="true" stored="true" />     
  2. <field name="pinyin" type="string" indexed="true" stored="false" multiValued="true"/>  
  3. <field name="abbre" type="string" indexed="true" stored="false" multiValued="true"/>  
  4. <field name="kwfreq" type="int" indexed="true" stored="true" />  
  5. <field name="_version_" type="long" indexed="true" stored="true"/>  
  6. <field name="suggest" type="suggest_text" indexed="true" stored="false" multiValued="true" />  

------------------multiValued表示字段是多值的-------------------------------------

XML/HTML Code复制内容到剪贴板

  1. <uniqueKey>kw</uniqueKey>  
  2. <defaultSearchField>suggest</defaultSearchField>  

说明:
kw为原始关键字
pinyin和abbre的multiValued=true,在使用solrj建此索引时,定义成集合类型即可:如关键字“重庆”的pinyin字段为{chongqing,zhongqing}, abbre字段为{cq, zq}
kwfreq为用户搜索关键的频率,用于查询的时候排序

-------------------------------------------------------

XML/HTML Code复制内容到剪贴板

  1. <copyField source="kw" dest="suggest" />  
  2. <copyField source="pinyin" dest="suggest" />  
  3. <copyField source="abbre" dest="suggest" />  

------------------suggest_text----------------------------------

XML/HTML Code复制内容到剪贴板

  1. <fieldType name="suggest_text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">  
  2.     <analyzer type="index">  
  3.             <tokenizer class="solr.KeywordTokenizerFactory" />  
  4.             <filter class="solr.SynonymFilterFactory"    
  5.                     synonyms="synonyms.txt"    
  6.                     ignoreCase="true"    
  7.                     expand="true" />  
  8.             <filter class="solr.StopFilterFactory"    
  9.                     ignoreCase="true"    
  10.                     words="stopwords.txt"    
  11.                     enablePositionIncrements="true" />  
  12.             <filter class="solr.LowerCaseFilterFactory" />  
  13.             <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />  
  14.     </analyzer>  
  15.     <analyzer type="query">  
  16.             <tokenizer class="solr.KeywordTokenizerFactory" />  
  17.             <filter class="solr.StopFilterFactory"    
  18.                     ignoreCase="true"    
  19.                     words="stopwords.txt"    
  20.                     enablePositionIncrements="true" />  
  21.             <filter class="solr.LowerCaseFilterFactory" />  
  22.             <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt" />  
  23.     </analyzer>  
  24. </fieldType>  

KeywordTokenizerFactory:这个分词器不进行任何分词!整个字符流变为单个词元。String域类型也有类似的效果,但是它不能配置文本分析的其它处理组件,比如大小写转换。任何用于排序和大部分Faceting功能的索引域,这个索引域只有能一个原始域值中的一个词元。

前缀查询构造:

Java Code复制内容到剪贴板

  1. private SolrQuery getSuggestQuery(String prefix, Integer limit) {   
  2.     SolrQuery solrQuery = new SolrQuery();   
  3.     StringBuilder sb = new StringBuilder();   
  4.     sb.append(“suggest:").append(prefix).append("*");  
  5.     solrQuery.setQuery(sb.toString());  
  6.     solrQuery.addField("kw");  
  7.     solrQuery.addField("kwfreq");  
  8.     solrQuery.addSort("kwfreq", SolrQuery.ORDER.desc);   
  9.     solrQuery.setStart(0);   
  10.     solrQuery.setRows(limit);   
  11.     return solrQuery;   
  12. }  

效果如下图所示:
2016331110400851.png (789×391)

四 : yii2实现分页,带搜索的分页功能示例

一、模型配置

事例会用到三个models。文章类别表和文章表用gii生成下即可,最后一个是搜索验证模型。其中,只讲下一个联表和搜索验证。其他不用操作。

1.文章表关联

 <?php //...other code //关联 public function getCate(){  return $this->hasOne(ArticleCate::className(),['id' => 'cid']);  } ?>

2.搜索模型

common/models/search/创建ArticleSearch.php

 <?php namespace commonmodelssearch; use Yii; use yiibaseModel; use yiidataActiveDataProvider; use commonmodelsArticle; class ArticleSearch extends Article {  //public $cname;//文章类别名  /**  * @inheritdoc  */  public function rules()  {  return [  [['cid','created_at', 'updated_at'], 'integer'],  [['id', 'desc','title','cover','content'], 'safe'],  ];  }  /**  * @inheritdoc  */  public function scenarios()  {  // bypass scenarios() implementation in the parent class  return Model::scenarios();  }  //搜索  public function search($params)  {  $query = Article::find();  // $query->joinWith(['cate']);//关联文章类别表  // $query->joinWith(['author' => function($query) { $query->from(['author' => 'users']); }]);  $dataProvider = new ActiveDataProvider([  'query' => $query,  'pagination' => [  'pageSize' => 2,  ],  ]);  // 从参数的数据中加载过滤条件,并验证  $this->load($params);  if (!$this->validate()) {  // uncomment the following line if you do not want to any records when validation fails  // $query->where('0=1');  return $dataProvider;  }  // 增加过滤条件来调整查询对象  $query->andFilterWhere([  // 'cname' => $this->cate.cname,  'title' => $this->title,  ]);  $query->andFilterWhere(['like', 'title', $this->title]);  //$query->andFilterWhere(['like', 'cate.cname', $this->cname]) ;  return $dataProvider;  } } 

二、分页使用

方式一

首先在控制器的动作中,创建分页对象并且为其填充数据:

 <?php //other code use yiidataPagination; public function actionArticlelist()  {  //分页读取类别数据  $model = Article::find()->with('cate');  $pagination = new Pagination([  'defaultPageSize' => 3,  'totalCount' => $model->count(),  ]);  $model = $model->orderBy('id ASC')  ->offset($pagination->offset)  ->limit($pagination->limit)  ->all();  return $this->render('index', [  'model' => $model,  'pagination' => $pagination,  ]);  } ?> 

其次在视图中我们输出的模板为当前页并通过分页对象链接到该页:

 <?php use yiiwidgetsLinkPager; use yiihelpersHtml; use yiihelpersUrl; //other code foreach ($models as $model) {  // 在这里显示 $model } // 显示分页 echo LinkPager::widget([  'pagination' => $pagination,  'firstPageLabel'=>"First",  'prevPageLabel'=>'Prev',  'nextPageLabel'=>'Next',  'lastPageLabel'=>'Last', ]); ?> 

方式二

控制器:

 <?php  $query = Article::find()->with('cate');  $provider = new ActiveDataProvider([  'query' => $query,  'pagination' => [  'pageSize' => 3,  ],  'sort' => [  'defaultOrder' => [  //'created_at' => SORT_DESC,  //'title' => SORT_ASC,  ]  ],  ]);  return $this->render('index', [  'model' => $query,  'dataProvider' => $provider  ]); ?> 

视图:

 <?php use yiigridGridView; echo GridView::widget([  'dataProvider' => $dataProvider,  //每列都有搜索框 控制器传过来$searchModel = new ArticleSearch(); //'filterModel' => $searchModel,  'layout'=> '{items}<div class="text-right tooltip-demo">{pager}</div>',  'pager'=>[  //'options'=>['class'=>'hidden']//关闭自带分页  'firstPageLabel'=>"First",  'prevPageLabel'=>'Prev',  'nextPageLabel'=>'Next',  'lastPageLabel'=>'Last',  ],  'columns' => [  //['class' => 'yiigridSerialColumn'],//序列号从1开始  // 数据提供者中所含数据所定义的简单的列  // 使用的是模型的列的数据  'id',  'username',  ['label'=>'文章类别', /*'attribute' => 'cid',产生一个a标签,点击可排序*/ 'value' => 'cate.cname' ],  ['label'=>'发布日期','format' => ['date', 'php:Y-m-d'],'value' => 'created_at'],  // 更复杂的列数据  ['label'=>'封面图','format'=>'raw','value'=>function($m){  return Html::img($m->cover,['class' => 'img-circle','width' => 30]);  }],  [  'class' => 'yiigridDataColumn', //由于是默认类型,可以省略 'value' => function ($data) {  return $data->name; // 如果是数组数据则为 $data['name'] ,例如,使用 SqlDataProvider 的情形。  },  ],  [  'class' => 'yiigridActionColumn',  'header' => '操作', 'template' => '{delete} {update}',//只需要展示删除和更新  /*'headerOptions' => ['width' => '80'],*/  'buttons' => [  'delete' => function($url, $model, $key){  return Html::a('<i class="glyphicon glyphicon-trash"></i> 删除',  ['artdel', 'id' => $key], ['class' => 'btn btn-default btn-xs',  'data' => ['confirm' => '你确定要删除文章吗?',]  ]);  },  'update' => function($url, $model, $key){  return Html::a('<i class="fa fa-file"></i> 更新',  ['artedit', 'id' => $key], ['class' => 'btn btn-default btn-xs']);  },  ],  ],  ], ]); ?> 

三、搜索带分页功能

  • 创建搜索模型(前面己做)
  • 控制传入数据
  • 视图显示控制器代码:

 <?php public function actionIndex() {  $searchModel = new ArticleSearch();  $dataProvider = $searchModel->search(Yii::$app->request->queryParams);  return $this->render('index', [  'searchModel' => $searchModel,  'dataProvider' => $dataProvider,  ]);  } ?> 

视图:

 <?php $form = ActiveForm::begin([  'action' => ['index'],  'method' => 'get',  'id' => 'cateadd-form',  'options' => ['class' => 'form-horizontal'], ]); ?>  <?= $form->field($searchModel, 'title',[  'options'=>['class'=>''],  'inputOptions' => ['placeholder' => '文章搜索','class' => 'input-sm form-control'], ])->label(false) ?>  <?= Html::submitButton('Go!', ['class' => 'btn btn-sm btn-primary']) ?> <?php ActiveForm::end(); ?> <?= GridView::widget([  'dataProvider' => $dataProvider,  'layout'=> '{items}<div class="text-right tooltip-demo">{pager}</div>',  'pager'=>[  //'options'=>['class'=>'hidden']//关闭自带分页  'firstPageLabel'=>"First",  'prevPageLabel'=>'Prev',  'nextPageLabel'=>'Next',  'lastPageLabel'=>'Last',  ],  //这部分和上面的分页是一样的 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持61阅读。

本文标题:android搜索功能实现-Twitter推出姓名实时搜索 便于发现虚假名人
本文地址: http://www.61k.com/1064423.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1