/** * Test to resolve the following issue. * * @link https://groups.google.com/forum/?fromgroups#!topic/elastica-php-client/zK_W_hClfvU * * @group unit */ public function testToArrayStructure() { $boolQuery = new BoolQuery(); $term1 = new Term(); $term1->setParam('interests', 84); $term2 = new Term(); $term2->setParam('interests', 92); $boolQuery->addShould($term1)->addShould($term2); $jsonString = '{"bool":{"should":[{"term":{"interests":84}},{"term":{"interests":92}}]}}'; $this->assertEquals($jsonString, json_encode($boolQuery->toArray())); }
/** * Set the type of match for the query and then add it to the bool container. * * @param QueryContract $query * @param Bool $container * @return Bool */ protected function addQueryToContainer(QueryContract $query, BoolQuery $container) { switch ($query->getType()) { case "must": $container->addMust($query->getQuery()); break; case "should": $container->addShould($query->getQuery()); break; case "must_not": $container->addMustNot($query->getQuery()); break; } return $container; }
/** * Perform a search based on the specified filter * * @param $typeTerms array * @param null $user * @param null $sortColumn * @param string $sortDirection * @param int $limit * @return array */ public function filteredSearch($typeTerms, $user = null, $sortColumn = null, $sortDirection = 'desc', $limit = 50) { $query = new Query(); $query->setFrom(0); $query->setSize($limit); $boolQuery = new BoolQuery(); // Handle 'must' filters if (isset($typeTerms['must'])) { foreach ($typeTerms['must'] as $type => $term) { $termQueryType = new TermQuery([$type => $term]); $boolQuery->addMust($termQueryType); } } // Handle 'should' filters if (isset($typeTerms['should'])) { foreach ($typeTerms['should'] as $type => $term) { $termQueryType = new TermQuery([$type => $term]); $boolQuery->addShould($termQueryType); } } $query->setQuery($boolQuery); if ($user) { $userId = $user->id; $termQueryUser = new TermQuery(['user_id' => $userId]); $boolQuery->addMust($termQueryUser); } if ($sortColumn) { $query->addSort([$sortColumn => ['order' => $sortDirection]]); } $resultSet = $this->getTypedIndex()->search($query); return $this->getModels($resultSet); }
/** * @param string[] $fields * @param string[] $nearMatchFields * @param string $queryString * @param string $nearMatchQuery * @return \Elastica\Query\Simple|\Elastica\Query\BoolQuery */ private function buildSearchTextQuery(array $fields, array $nearMatchFields, $queryString, $nearMatchQuery) { $queryForMostFields = $this->buildSearchTextQueryForFields($fields, $queryString, $this->config->getElement('CirrusSearchPhraseSlop', 'default'), false); if ($nearMatchQuery) { // Build one query for the full text fields and one for the near match fields so that // the near match can run unescaped. $BoolQuery = new \Elastica\Query\BoolQuery(); $BoolQuery->setMinimumNumberShouldMatch(1); $BoolQuery->addShould($queryForMostFields); $nearMatch = new \Elastica\Query\MultiMatch(); $nearMatch->setFields($nearMatchFields); $nearMatch->setQuery($nearMatchQuery); $BoolQuery->addShould($nearMatch); return $BoolQuery; } return $queryForMostFields; }
/** * @param BoolOr $nestedOrFilter Nested or filter * @param string $nestedProperty Nested property (can be 'variants') */ private function addAvailableProductsVariantFilters(BoolOr $nestedOrFilter, $nestedProperty) { $variantsNestedBool = new BoolQuery(); $variantsNestedBool->setMinimumNumberShouldMatch(1); $availableOn = new QueryRange($nestedProperty . '.availableOn', array('lte' => "now")); $variantsNestedBool->addMust($availableOn); $availableUntil = new Filtered(); $availableUntilFilter = new BoolOr(); $availableUntilNull = new Missing($nestedProperty . '.availableUntil'); $availableUntilFilter->addFilter($availableUntilNull); $availableUntilGte = new FilterRange($nestedProperty . '.availableUntil', array('gte' => time())); $availableUntilFilter->addFilter($availableUntilGte); $availableUntil->setFilter($availableUntilFilter); $variantsNestedBool->addMust($availableUntil); $availableOnDemand = new QueryTerm(array($nestedProperty . '.availableOnDemand' => true)); $variantsNestedBool->addShould($availableOnDemand); $onHand = new QueryRange($nestedProperty . '.onHand', array('gt' => 0)); $variantsNestedBool->addShould($onHand); $nested = new Nested(); $nested->setPath($nestedProperty); $nested->setQuery($variantsNestedBool); $nestedOrFilter->addFilter($nested); }
/** * search page index controller * * @param Request $request * @param int $page * @return \Symfony\Component\HttpFoundation\Response */ public function indexAction(Request $request, $page = 1) { $searchManager = $this->get('ojs_search_manager'); $journalId = null; $getRoles = $request->query->get('role_filters'); $getSubjects = $request->query->get('subject_filters'); $getJournals = $request->query->get('journal_filters'); $getLocales = $request->query->get('locale_filters'); $getPublishers = $request->query->get('publisher_filters'); $getIndexes = $request->query->get('index_filters'); $roleFilters = !empty($getRoles) ? explode(',', $getRoles) : []; $subjectFilters = !empty($getSubjects) ? explode(',', $getSubjects) : []; $journalFilters = !empty($getJournals) ? explode(',', $getJournals) : []; $localeFilters = !empty($getLocales) ? explode(',', $getLocales) : []; $publisherFilters = !empty($getPublishers) ? explode(',', $getPublishers) : []; $indexFilters = !empty($getIndexes) ? explode(',', $getIndexes) : []; $queryType = $request->query->has('type') ? $request->get('type') : 'basic'; $query = filter_var($request->get('q'), FILTER_SANITIZE_STRING); $section = filter_var($request->get('section'), FILTER_SANITIZE_STRING); $searcher = $this->get('fos_elastica.index.search'); $searchQuery = new Query('_all'); $boolQuery = new Query\BoolQuery(); $match = new Query\Match(); $match->setField('published', false); $boolQuery->addMustNot($match); //set query according to query type if ($queryType == 'basic') { $fieldQuery = new Query\Prefix(); $fieldQuery->setPrefix('_all', $query); $boolQuery->addMust($fieldQuery); } elseif ($queryType == 'advanced') { $parseQuery = $searchManager->parseSearchQuery($query); foreach ($parseQuery as $searchTerm) { $condition = $searchTerm['condition']; $advancedFieldQuery = new Query\MultiMatch(); $advancedFieldQuery->setFields([$searchTerm['searchField']]); $advancedFieldQuery->setQuery($searchTerm['searchText']); if ($condition == 'AND') { $boolQuery->addMust($advancedFieldQuery); } elseif ($condition == 'OR') { $boolQuery->addShould($advancedFieldQuery); } elseif ($condition == 'NOT') { $boolQuery->addMustNot($advancedFieldQuery); } } } elseif ($queryType == 'tag') { $regexpQuery = new Query\Regexp(); $regexpQuery->setParams(['tags' => ".*" . $query . ".*"]); $boolQuery->addMust($regexpQuery); } elseif ($queryType == 'injournal') { $journalId = $request->get('journalId'); $boolQuery->setParams($searchManager->getSearchInJournalQuery($journalId, $query)); } //set aggregations if requested if (!empty($roleFilters) || !empty($subjectFilters) || !empty($journalFilters) || !empty($localeFilters) || !empty($publisherFilters)) { foreach ($roleFilters as $role) { $match = new Query\Match(); $match->setField('user.userJournalRoles.role.name', $role); $boolQuery->addMust($match); } foreach ($subjectFilters as $subject) { $match = new Query\Match(); $match->setField('subjects', $subject); $boolQuery->addMust($match); } foreach ($journalFilters as $journal) { $match = new Query\Match(); $match->setField('user.userJournalRoles.journal.title', $journal); $boolQuery->addMust($match); } foreach ($localeFilters as $locale) { $match = new Query\Match(); $match->setField('translations.locale', $locale); $boolQuery->addMust($match); } foreach ($publisherFilters as $publisher) { $match = new Query\Match(); $match->setField('publisher.name', $publisher); $boolQuery->addMust($match); } foreach ($indexFilters as $index) { $match = new Query\Match(); $match->setField('journalIndexs.index.name', $index); $boolQuery->addMust($match); } } //set our boolean query $searchQuery->setQuery($boolQuery); //get all result $searchQuery->setSize(1000); //get role aggregation $roleAgg = new Aggregation\Terms('roles'); $roleAgg->setField('userJournalRoles.role.name'); $roleAgg->setOrder('_term', 'asc'); $roleAgg->setSize(0); $searchQuery->addAggregation($roleAgg); //get subject aggregation $subjectAgg = new Aggregation\Terms('subjects'); $subjectAgg->setField('subjects.subject'); $subjectAgg->setOrder('_term', 'asc'); $subjectAgg->setSize(0); $searchQuery->addAggregation($subjectAgg); //get journal aggregation $journalAgg = new Aggregation\Terms('journals'); $journalAgg->setField('journal.title.raw'); $journalAgg->setOrder('_term', 'asc'); $journalAgg->setSize(0); $searchQuery->addAggregation($journalAgg); $localeAgg = new Aggregation\Terms('locales'); $localeAgg->setField('translations.locale'); $localeAgg->setOrder('_term', 'asc'); $localeAgg->setSize(0); $searchQuery->addAggregation($localeAgg); $publisherAgg = new Aggregation\Terms('publishers'); $publisherAgg->setField('publisher.name.raw'); $publisherAgg->setOrder('_term', 'asc'); $publisherAgg->setSize(0); $searchQuery->addAggregation($publisherAgg); $indexAgg = new Aggregation\Terms('indexes'); $indexAgg->setField('journalIndexs.index.name.raw'); $indexAgg->setOrder('_term', 'asc'); $indexAgg->setSize(0); $searchQuery->addAggregation($indexAgg); /** * @var ResultSet $resultData */ $resultData = $searcher->search($searchQuery); $roles = $resultData->getAggregation('roles')['buckets']; $subjects = $resultData->getAggregation('subjects')['buckets']; $journals = $resultData->getAggregation('journals')['buckets']; $locales = $resultData->getAggregation('locales')['buckets']; $publishers = $resultData->getAggregation('publishers')['buckets']; $indexes = $resultData->getAggregation('indexes')['buckets']; if ($resultData->count() > 0) { /** * manipulate result data for easily use on template */ $results = $searchManager->buildResultsObject($resultData, $section); /** * if search section is not defined or empty redirect to first result section */ if (empty($section)) { $section = array_keys($results)[0]; $redirectParams = array_merge($request->query->all(), ['section' => $section]); return $this->redirectToRoute('ojs_search_index', $redirectParams); } else { /** * if section result is empty redirect to first that have result section */ if (!isset($results[$section])) { foreach ($results as $resultKey => $result) { if ($result['total_item'] > 0) { $redirectParams = array_merge($request->query->all(), ['section' => $resultKey]); return $this->redirectToRoute('ojs_search_index', $redirectParams); } } } } $adapter = new ArrayAdapter($results[$section]['data']); $pagerfanta = new Pagerfanta($adapter); $pagerfanta->setMaxPerPage(20); $pagerfanta->setCurrentPage($page); $results[$section]['data'] = $pagerfanta->getCurrentPageResults(); /** * add search query to query history * history data stores on session */ $this->addQueryToHistory($request, $query, $queryType, $resultData->count()); $data = ['journalId' => $journalId, 'results' => $results, 'query' => $query, 'queryType' => $queryType, 'section' => $section, 'total_count' => $searchManager->getTotalHit(), 'roles' => $roles, 'subjects' => $subjects, 'locales' => $locales, 'journals' => $journals, 'publishers' => $publishers, 'indexes' => $indexes, 'role_filters' => $roleFilters, 'subject_filters' => $subjectFilters, 'journal_filters' => $journalFilters, 'locale_filters' => $localeFilters, 'publisher_filters' => $publisherFilters, 'index_filters' => $indexFilters, 'pagerfanta' => $pagerfanta, 'page' => $page]; } else { $data = ['journalId' => $journalId, 'query' => $query, 'queryType' => $queryType, 'total_count' => $searchManager->getTotalHit(), 'journals' => []]; } return $this->render('OjsSiteBundle:Search:index.html.twig', $data); }