http://my.oschina.net/u/730537/blog/288703这是初始化创建index和mapping的代码:$elasticaClient = new \Elastica\Client(array('host'=>'localhost','port'=>9200)); // Load index $elasticaIndex = $elasticaClient->getIndex('links'); // Create the index new // 创建index的参数自行参见官网,就不一一解释了 $elasticaIndex->create( array( 'number_of_shards' => 4, 'number_of_replicas' => 1, 'analysis' => array( 'analyzer' => array( 'indexAnalyzer' => array( 'type' => 'custom', 'tokenizer' => 'standard', 'filter' => array('lowercase', 'mySnowball') ), 'searchAnalyzer' => array( 'type' => 'custom', 'tokenizer' => 'standard', 'filter' => array('standard', 'lowercase', 'mySnowball') ) ), 'filter' => array( 'mySnowball' => array( 'type' => 'snowball', 'language' => 'German' ) ) ) ), true ); //创建media的mapping,作为父级 $mediaType = $elasticaIndex->getType('media'); // Define mapping $mapping = new \Elastica\Type\Mapping(); $mapping->setType($mediaType); $mapping->setParam('index_analyzer', 'indexAnalyzer'); $mapping->setParam('search_analyzer', 'searchAnalyzer'); // Define boost field $mapping->setParam('_boost', array('name' => '_boost', 'null_value' => 1.0)); // Set mapping // 定义media的字段和属性 $mapping->setProperties(array( 'id' => array('type' => 'string', 'include_in_all' => FALSE), 'media_name' => array('type' => 'string', 'include_in_all' => TRUE), 'tstamp' => array('type' => 'date', 'include_in_all' => FALSE), 'language' => array('type' => 'integer', 'include_in_all' => FALSE), '_boost' => array('type' => 'float', 'include_in_all' => FALSE) )); // Send mapping to type // 保存media的mapping $mapping->send(); //创建question的mapping,父级为media $questionType = $elasticaIndex->getType('question'); // Define mapping $mapping = new \Elastica\Type\Mapping(); $mapping->setType($questionType); $mapping->setParam('index_analyzer', 'indexAnalyzer'); $mapping->setParam('search_analyzer', 'searchAnalyzer'); // Define boost field $mapping->setParam('_boost', array('name' => '_boost', 'null_value' => 1.0)); // Set mapping // question的字段和属性 $mapping->setProperties(array( 'id' => array('type' => 'string', 'include_in_all' => FALSE), 'level_one' => array('type' => 'integer', 'include_in_all' => FALSE), 'level_two' => array('type' => 'integer', 'include_in_all' => FALSE), 'level_thr' => array('type' => 'integer', 'include_in_all' => FALSE), 'top_level' => array('type' => 'string', 'include_in_all' => FALSE), 'cat_id' => array('type' => 'integer', 'include_in_all' => FALSE), 'quest_hash' => array('type' => 'string', 'include_in_all' => TRUE), 'content' => array('type' => 'string', 'include_in_all' => TRUE), 'view_num' => array('type' => 'integer', 'include_in_all' => FALSE), 'like_num' => array('type' => 'integer', 'include_in_all' => FALSE), '_boost' => array('type' => 'float', 'include_in_all' => FALSE) )); $mapping->setParent("media");//指定question的父类 // Send mapping to type // 保存question的mapping $mapping->send();上面虽然是PHP代码,但是最终生成的也是一个url请求。下面说搜索,搜索的话ES是通过query、filter等来处理的,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这里搜索是这样的,根据media的media_name做query_string搜索,然后对media进行has_child的filter搜索,has_child搜索内使用boolAnd的filter来筛选。下面是搜索的代码:$query = new \Elastica\Query();if (!empty($input['key'])) { //针对media的media_name字段设置QueryString查询 $elasticaQueryString = new \Elastica\Query\QueryString(); $elasticaQueryString->setFields(array("media.media_name")); $elasticaQueryString->setQuery($input['key']); // $query->setQuery($elasticaQueryString);}else { $query->setQuery(new MatchAll()); //命中全部纪录}$language_bool = false;$elasticaFilterAnd = new \Elastica\Filter\BoolAnd();//language也是针对media,设置BoolAnd查询if (isset($input['language']) && !empty($input['language'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('language', intval($input['language'])); $elasticaFilterAnd->addFilter($filterl1); $language_bool = true;}////对子集进行筛选查询,使用has_child$subFilterAnd = new \Elastica\Filter\BoolAnd();$bool = false;// 一级分类条件if (isset($input['level_one']) && !empty($input['level_one'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('level_one', intval($input['level_one'])); $subFilterAnd->addFilter($filterl1); $bool = true;}// 二级分类条件if (isset($input['level_two']) && !empty($input['level_two'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('level_two', intval($input['level_two'])); $subFilterAnd->addFilter($filterl1); $bool = true;}// 三级分类条件if (isset($input['level_thr']) && !empty($input['level_thr'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('level_thr', intval($input['level_thr'])); $subFilterAnd->addFilter($filterl1); $bool = true;}// 直接指定分类ID查询if (isset($input['cat_id']) && !empty($input['cat_id'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('cat_id', intval($input['cat_id'])); $subFilterAnd->addFilter($filterl1); $bool = true;}// 分类属性查询if (isset($input['top_level']) && !empty($input['top_level'])) { $filterl1 = new \Elastica\Filter\Term(); $filterl1->setTerm('top_level', $input['top_level']); $subFilterAnd->addFilter($filterl1); $bool = true;}if($bool){ // 声明一个查询,用于放入子查询 $subQuery = new \Elastica\Query(); // 使用filteredquery,融合query和filter $filteredQuery = new \Elastica\Query\Filtered(new MatchAll(),$subFilterAnd); // 添加filterquery到子查询 $subQuery->setQuery($filteredQuery); // 声明hasChildFilter,声明的时候就指定子查询的内容,指定查询的子表(也就是TYPE)为question $filterHasChild = new \Elastica\Filter\HasChild($subQuery,"question"); // 将拥有子类查询增加到父级查询的filter中 $elasticaFilterAnd->addFilter($filterHasChild);}if($bool || $language_bool){ // 将filter增加到父查询汇中 $query->setFilter($elasticaFilterAnd);}//// $query->setFrom($start); // Where to start?$query->setLimit($limit); // How many?////Search on the index.$elasticaResultSet = $elasticaIndex->search($query);在处理过程中,感谢之前的哥们留下的代码,至少不是摸瞎。感谢同事搞的谷歌搜索,一般人我不告诉他,大家可以去试试 另客网,首页的搜索框里面,选择谷歌。http://www.links123.com/部分借鉴来自于这里:http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/