コード例 #1
0
ファイル: translator.php プロジェクト: Blu2z/implsk
 /**
  * @param nc_search_query_expression_phrase $expression
  * @return string
  */
 protected function translate_phrase(nc_search_query_expression_phrase $expression)
 {
     $this->stack[] = "phrase";
     // Given a phrase "one two", where "two" has forms of "two1" and "two2":
     //   - added to the main FTS condition: ((+one +two1) (+one +two2))
     //     (this query is used to fetch rows which contain these words using a FTS index)
     //   - added to the query: REGEXP condition(s) to fetch only rows where these terms
     //     come in sequence (REGEXP is used because there could be several
     //     variants of the same term in the index in the form "one two1|two2")
     $term_combinations = array();
     $regexps = array();
     /** @var $item nc_search_query_expression_term */
     foreach ($expression->get_items() as $item) {
         // "for each term in the phrase"
         $item_codes = $this->process_term($item);
         if ($item_codes[0]) {
             // not a stop word
             $brackets = $this->get_brackets(count($item_codes) > 1);
             $regexps[] = $brackets[0] . join("|", array_filter($item_codes)) . $brackets[1];
         }
         if (count($term_combinations) == 0) {
             // it's a first (meaningful) term
             $term_combinations = $item_codes;
         } else {
             // produce all possible combinations
             $previous_state = $term_combinations;
             $term_combinations = array();
             foreach ($previous_state as $p) {
                 foreach ($item_codes as $c) {
                     $not_empty = strlen($c) > 0;
                     // might be a stop word
                     $term_combinations[] = $p . ($not_empty ? " {$c}" : "");
                 }
             }
         }
     }
     // there can be a space in the beginning if the first term is stop word
     if ($term_combinations && $term_combinations[0][0] == " ") {
         $term_combinations = array_map('trim', $term_combinations);
     }
     // all terms in the phrase are stop words?!
     if (!$term_combinations || !$term_combinations[0]) {
         return "";
     }
     // make FTS query to pre-filter results before running regexp match
     $fts_query = "";
     if (!$expression->is_excluded()) {
         $brackets = $this->get_brackets(count($term_combinations) > 1);
         $fts_query = "{$brackets['0']}(+" . join(")(+", $term_combinations) . "){$brackets['1']}";
         $fts_query = strtr($fts_query, array(" " => " +", ")(" => ") ("));
     }
     // add exact sequence condition
     $table_names = $this->get_table_names($expression);
     // [.vertical-line.] is not redundant: it prevents from matching a partial code
     $term_boundary = "([[.vertical-line.]][^[.space.][.slash.]]+)?[[.space.]]";
     $skip_regexps = false;
     $num_regexps = count($regexps);
     if ($expression->get_distance()) {
         // it's a "proximity search"
         if ($num_regexps < 2 || $num_regexps > (int) nc_search::get_setting("DatabaseIndex_MaxProximityTerms")) {
             // the proximity phrase is too long (or too short)!
             $skip_regexps = true;
         } else {
             // get all possible permutations
             $skipped_term = "[^[.space.][.slash.]]+[[.space.]]";
             $distance = min((int) nc_search::get_setting("DatabaseIndex_MaxProximityDistance"), $expression->get_distance());
             $gaps = $distance == 1 ? $term_boundary : "{$term_boundary}({$skipped_term}){0,{$distance}}";
             $regexps = $this->permute($regexps, $gaps);
         }
     } else {
         // ordinary phrase, distance=0
         if ($num_regexps > 1) {
             $regexps = join($term_boundary, $regexps);
         } else {
             $skip_regexps = true;
         }
     }
     if (!$skip_regexps) {
         $this->query_builder->add_field_regexps($table_names, $regexps, $expression->is_excluded());
     } elseif ($expression->get_field()) {
         $this->add_field_matches($expression, $fts_query);
     }
     // remove "phrase" from the stack
     array_pop($this->stack);
     // done
     return $fts_query;
 }
コード例 #2
0
ファイル: plaintext.php プロジェクト: Blu2z/implsk
 /**
  * @param nc_search_query_expression_phrase $expression
  * @return void
  */
 protected function translate_phrase(nc_search_query_expression_phrase $expression)
 {
     $terms = array();
     foreach ($expression->get_items() as $term) {
         $terms[] = $term->get_value();
     }
     $string = 'PHRASE "' . join(" ", $terms) . '"' . $this->get_modifiers($expression);
     $this->print_line($string);
 }