Sets the query string.
public setFieldQuery ( string $field, string $query ) | ||
$field | string | |
$query | string |
/** * Find all documents where the values are matched in the field. The type option * allows you to specify the type of match, can be either phrase or phrase_prefix. * * The phrase match analyzes the text and creates a phrase query out of the * analyzed text. * * The phrase prefix match is the same as phrase, except that it allows for * prefix matches on the last term in the text. * * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html * * @param string $field The field to search in the index * @param string $query The values to search for * @param string $type The match type * @param bool $fuzzy Set whether the match should be fuzzy * @return Query */ public function match($field, $query, $type = 'phrase', $fuzzy = false) { $match = new Match(); $match->setFieldQuery($field, $query); $match->setFieldType($field, $type); if ($fuzzy) { $match->setFieldFuzziness($field, 'AUTO'); } $query = $this->newQuery($match); $this->query[] = $query; return $query; }
/** * Perform a search on messages using Elasticsearch * * @param string $query The query string * @return Message[] The results of the search */ private function elasticSearch($query) { $finder = \Service::getContainer()->get('fos_elastica.finder.search'); $boolQuery = new Bool(); // We have only stored "active" messages and groups on Elasticsearch's // database, so there is no check for that again if ($this->player) { // Make sure that the parent of the message (i.e. the group that the // message belongs into) has the current player as its member $recipientQuery = new Term(); $recipientQuery->setTerm('members', $this->player->getId()); $parentQuery = new HasParent($recipientQuery, 'group'); $boolQuery->addMust($parentQuery); } $fieldQuery = new Match(); $fieldQuery->setFieldQuery('content', $query)->setFieldFuzziness('content', 'auto'); $boolQuery->addMust($fieldQuery); return $finder->find($boolQuery); }
public function testMatchPhrasePrefix() { $client = $this->_getClient(); $index = $client->getIndex('test'); $index->create(array(), true); $type = $index->getType('test'); $doc = new Document(1, array('name' => 'Basel-Stadt')); $type->addDocument($doc); $doc = new Document(2, array('name' => 'New York')); $type->addDocument($doc); $doc = new Document(3, array('name' => 'New Hampshire')); $type->addDocument($doc); $doc = new Document(4, array('name' => 'Basel Land')); $type->addDocument($doc); $index->refresh(); $field = 'name'; $type = 'phrase_prefix'; $query = new Match(); $query->setFieldQuery($field, 'New'); $query->setFieldType($field, $type); $resultSet = $index->search($query); $this->assertEquals(2, $resultSet->count()); }
/** * If there is any boosting to be done munge the the current query to get it right. */ private function installBoosts() { // Quick note: At the moment ".isEmpty()" is _much_ faster then ".empty". Never // use ".empty". See https://github.com/elasticsearch/elasticsearch/issues/5086 if ($this->sort !== 'relevance') { // Boosts are irrelevant if you aren't sorting by, well, relevance return; } $functionScore = new \Elastica\Query\FunctionScore(); $useFunctionScore = false; // Customize score by boosting based on incoming links count if ($this->boostLinks) { $useFunctionScore = true; if ($this->config->getElement('CirrusSearchWikimediaExtraPlugin', 'field_value_factor_with_default')) { $functionScore->addFunction('field_value_factor_with_default', array('field' => 'incoming_links', 'modifier' => 'log2p', 'missing' => 0)); } else { $scoreBoostExpression = "log10(doc['incoming_links'].value + 2)"; $functionScore->addScriptScoreFunction(new \Elastica\Script($scoreBoostExpression, null, 'expression')); } } // Customize score by decaying a portion by time since last update if ($this->preferRecentDecayPortion > 0 && $this->preferRecentHalfLife > 0) { // Convert half life for time in days to decay constant for time in milliseconds. $decayConstant = log(2) / $this->preferRecentHalfLife / 86400000; $parameters = array('decayConstant' => $decayConstant, 'decayPortion' => $this->preferRecentDecayPortion, 'nonDecayPortion' => 1 - $this->preferRecentDecayPortion, 'now' => time() * 1000); // e^ct where t is last modified time - now which is negative $exponentialDecayExpression = "exp(decayConstant * (doc['timestamp'].value - now))"; if ($this->preferRecentDecayPortion !== 1.0) { $exponentialDecayExpression = "{$exponentialDecayExpression} * decayPortion + nonDecayPortion"; } $functionScore->addScriptScoreFunction(new \Elastica\Script($exponentialDecayExpression, $parameters, 'expression')); $useFunctionScore = true; } // Add boosts for pages that contain certain templates if ($this->boostTemplates) { foreach ($this->boostTemplates as $name => $boost) { $match = new \Elastica\Query\Match(); $match->setFieldQuery('template', $name); $filterQuery = new \Elastica\Filter\Query($match); $filterQuery->setCached(true); $functionScore->addBoostFactorFunction($boost, $filterQuery); } $useFunctionScore = true; } // Add boosts for namespaces $namespacesToBoost = $this->namespaces ?: MWNamespace::getValidNamespaces(); if ($namespacesToBoost) { // Group common weights together and build a single filter per weight // to save on filters. $weightToNs = array(); foreach ($namespacesToBoost as $ns) { $weight = $this->getBoostForNamespace($ns); $weightToNs[(string) $weight][] = $ns; } if (count($weightToNs) > 1) { unset($weightToNs['1']); // That'd be redundant. foreach ($weightToNs as $weight => $namespaces) { $filter = new \Elastica\Filter\Terms('namespace', $namespaces); $functionScore->addBoostFactorFunction($weight, $filter); $useFunctionScore = true; } } } // Boost pages in a user's language $userLang = $this->config->getUserLanguage(); $userWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'user'); if ($userWeight) { $functionScore->addBoostFactorFunction($userWeight, new \Elastica\Filter\Term(array('language' => $userLang))); $useFunctionScore = true; } // And a wiki's language, if it's different $wikiWeight = $this->config->getElement('CirrusSearchLanguageWeight', 'wiki'); if ($userLang != $this->config->get('LanguageCode') && $wikiWeight) { $functionScore->addBoostFactorFunction($wikiWeight, new \Elastica\Filter\Term(array('language' => $this->config->get('LanguageCode')))); $useFunctionScore = true; } if (!$useFunctionScore) { // Nothing to do return; } // The function score is done as a rescore on top of everything else $this->rescore[] = array('window_size' => $this->config->get('CirrusSearchFunctionRescoreWindowSize'), 'query' => array('rescore_query' => $functionScore, 'query_weight' => 1.0, 'rescore_query_weight' => 1.0, 'score_mode' => 'multiply')); }