1. http://my.oschina.net/u/730537/blog/288703
    2. 这是初始化创建indexmapping的代码:
    3. $elasticaClient = new \Elastica\Client(array('host'=>'localhost','port'=>9200));
    4. // Load index
    5. $elasticaIndex = $elasticaClient->getIndex('links');
    6. // Create the index new
    7. // 创建index的参数自行参见官网,就不一一解释了
    8. $elasticaIndex->create(
    9. array(
    10. 'number_of_shards' => 4,
    11. 'number_of_replicas' => 1,
    12. 'analysis' => array(
    13. 'analyzer' => array(
    14. 'indexAnalyzer' => array(
    15. 'type' => 'custom',
    16. 'tokenizer' => 'standard',
    17. 'filter' => array('lowercase', 'mySnowball')
    18. ),
    19. 'searchAnalyzer' => array(
    20. 'type' => 'custom',
    21. 'tokenizer' => 'standard',
    22. 'filter' => array('standard', 'lowercase', 'mySnowball')
    23. )
    24. ),
    25. 'filter' => array(
    26. 'mySnowball' => array(
    27. 'type' => 'snowball',
    28. 'language' => 'German'
    29. )
    30. )
    31. )
    32. ),
    33. true
    34. );
    35. //创建media的mapping,作为父级
    36. $mediaType = $elasticaIndex->getType('media');
    37. // Define mapping
    38. $mapping = new \Elastica\Type\Mapping();
    39. $mapping->setType($mediaType);
    40. $mapping->setParam('index_analyzer', 'indexAnalyzer');
    41. $mapping->setParam('search_analyzer', 'searchAnalyzer');
    42. // Define boost field
    43. $mapping->setParam('_boost', array('name' => '_boost', 'null_value' => 1.0));
    44. // Set mapping
    45. // 定义media的字段和属性
    46. $mapping->setProperties(array(
    47. 'id' => array('type' => 'string', 'include_in_all' => FALSE),
    48. 'media_name' => array('type' => 'string', 'include_in_all' => TRUE),
    49. 'tstamp' => array('type' => 'date', 'include_in_all' => FALSE),
    50. 'language' => array('type' => 'integer', 'include_in_all' => FALSE),
    51. '_boost' => array('type' => 'float', 'include_in_all' => FALSE)
    52. ));
    53. // Send mapping to type
    54. // 保存media的mapping
    55. $mapping->send();
    56. //创建question的mapping,父级为media
    57. $questionType = $elasticaIndex->getType('question');
    58. // Define mapping
    59. $mapping = new \Elastica\Type\Mapping();
    60. $mapping->setType($questionType);
    61. $mapping->setParam('index_analyzer', 'indexAnalyzer');
    62. $mapping->setParam('search_analyzer', 'searchAnalyzer');
    63. // Define boost field
    64. $mapping->setParam('_boost', array('name' => '_boost', 'null_value' => 1.0));
    65. // Set mapping
    66. // question的字段和属性
    67. $mapping->setProperties(array(
    68. 'id' => array('type' => 'string', 'include_in_all' => FALSE),
    69. 'level_one' => array('type' => 'integer', 'include_in_all' => FALSE),
    70. 'level_two' => array('type' => 'integer', 'include_in_all' => FALSE),
    71. 'level_thr' => array('type' => 'integer', 'include_in_all' => FALSE),
    72. 'top_level' => array('type' => 'string', 'include_in_all' => FALSE),
    73. 'cat_id' => array('type' => 'integer', 'include_in_all' => FALSE),
    74. 'quest_hash' => array('type' => 'string', 'include_in_all' => TRUE),
    75. 'content' => array('type' => 'string', 'include_in_all' => TRUE),
    76. 'view_num' => array('type' => 'integer', 'include_in_all' => FALSE),
    77. 'like_num' => array('type' => 'integer', 'include_in_all' => FALSE),
    78. '_boost' => array('type' => 'float', 'include_in_all' => FALSE)
    79. ));
    80. $mapping->setParent("media");//指定question的父类
    81. // Send mapping to type
    82. // 保存question的mapping
    83. $mapping->send();
    84. 上面虽然是PHP代码,但是最终生成的也是一个url请求。
    85. 下面说搜索,搜索的话ES是通过queryfilter等来处理的,query里面有很多不同的方式,参见:http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-queries.html,filter也是,参见http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-filters.html
    86. 这里搜索是这样的,根据mediamedia_namequery_string搜索,然后对media进行has_childfilter搜索,has_child搜索内使用boolAndfilter来筛选。
    87. 下面是搜索的代码:
    88. $query = new \Elastica\Query();
    89. if (!empty($input['key'])) {
    90. //针对media的media_name字段设置QueryString查询
    91. $elasticaQueryString = new \Elastica\Query\QueryString();
    92. $elasticaQueryString->setFields(array("media.media_name"));
    93. $elasticaQueryString->setQuery($input['key']);
    94. //
    95. $query->setQuery($elasticaQueryString);
    96. }else {
    97. $query->setQuery(new MatchAll()); //命中全部纪录
    98. }
    99. $language_bool = false;
    100. $elasticaFilterAnd = new \Elastica\Filter\BoolAnd();
    101. //language也是针对media,设置BoolAnd查询
    102. if (isset($input['language']) && !empty($input['language'])) {
    103. $filterl1 = new \Elastica\Filter\Term();
    104. $filterl1->setTerm('language', intval($input['language']));
    105. $elasticaFilterAnd->addFilter($filterl1);
    106. $language_bool = true;
    107. }
    108. //
    109. //对子集进行筛选查询,使用has_child
    110. $subFilterAnd = new \Elastica\Filter\BoolAnd();
    111. $bool = false;
    112. // 一级分类条件
    113. if (isset($input['level_one']) && !empty($input['level_one'])) {
    114. $filterl1 = new \Elastica\Filter\Term();
    115. $filterl1->setTerm('level_one', intval($input['level_one']));
    116. $subFilterAnd->addFilter($filterl1);
    117. $bool = true;
    118. }
    119. // 二级分类条件
    120. if (isset($input['level_two']) && !empty($input['level_two'])) {
    121. $filterl1 = new \Elastica\Filter\Term();
    122. $filterl1->setTerm('level_two', intval($input['level_two']));
    123. $subFilterAnd->addFilter($filterl1);
    124. $bool = true;
    125. }
    126. // 三级分类条件
    127. if (isset($input['level_thr']) && !empty($input['level_thr'])) {
    128. $filterl1 = new \Elastica\Filter\Term();
    129. $filterl1->setTerm('level_thr', intval($input['level_thr']));
    130. $subFilterAnd->addFilter($filterl1);
    131. $bool = true;
    132. }
    133. // 直接指定分类ID查询
    134. if (isset($input['cat_id']) && !empty($input['cat_id'])) {
    135. $filterl1 = new \Elastica\Filter\Term();
    136. $filterl1->setTerm('cat_id', intval($input['cat_id']));
    137. $subFilterAnd->addFilter($filterl1);
    138. $bool = true;
    139. }
    140. // 分类属性查询
    141. if (isset($input['top_level']) && !empty($input['top_level'])) {
    142. $filterl1 = new \Elastica\Filter\Term();
    143. $filterl1->setTerm('top_level', $input['top_level']);
    144. $subFilterAnd->addFilter($filterl1);
    145. $bool = true;
    146. }
    147. if($bool){
    148. // 声明一个查询,用于放入子查询
    149. $subQuery = new \Elastica\Query();
    150. // 使用filteredquery,融合query和filter
    151. $filteredQuery = new \Elastica\Query\Filtered(new MatchAll(),$subFilterAnd);
    152. // 添加filterquery到子查询
    153. $subQuery->setQuery($filteredQuery);
    154. // 声明hasChildFilter,声明的时候就指定子查询的内容,指定查询的子表(也就是TYPE)为question
    155. $filterHasChild = new \Elastica\Filter\HasChild($subQuery,"question");
    156. // 将拥有子类查询增加到父级查询的filter中
    157. $elasticaFilterAnd->addFilter($filterHasChild);
    158. }
    159. if($bool || $language_bool){
    160. // 将filter增加到父查询汇中
    161. $query->setFilter($elasticaFilterAnd);
    162. }
    163. //
    164. //
    165. $query->setFrom($start); // Where to start?
    166. $query->setLimit($limit); // How many?
    167. //
    168. //Search on the index.
    169. $elasticaResultSet = $elasticaIndex->search($query);
    170. 在处理过程中,感谢之前的哥们留下的代码,至少不是摸瞎。感谢同事搞的谷歌搜索,一般人我不告诉他,大家可以去试试 另客网,首页的搜索框里面,选择谷歌。
    171. http://www.links123.com/
    172. 部分借鉴来自于这里:http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/