source: subversion/sites/namefinder/php/word.php @ 17445

Last change on this file since 17445 was 8132, checked in by david, 11 years ago

namefinder version 2 - incremental updates; word indexes

File size: 3.3 KB
Line 
1<?php
2
3/* Index of names by word. This allows for efficient searching without wildcards,
4   and for variations in names */
5
6include_once('canonical.php');
7include_once('named.php');
8
9class word {
10
11  var $word;    /* a canonical word in the index */
12
13  var $ordinal; /* the ordinal position of the word in the canonical name.
14                   e.g. if the canonical  name is 'walter;matthau;avenue'
15                   then 'walter' is word 1, 'matthau' is 2 and so on. */
16
17  var $firstword; /* booleans for whether this word is the first or last in a phrase */
18  var $lastword;  /* aids exact macthing */
19
20  var $region;  /* the region number of the record this index term refers to.
21                   Not strictly necessary, but allows entries to be culled by
22                   region before they are joined to the named table during a search */
23
24  var $id;      /* the id of the record this index term refers to in the named table */
25
26  // --------------------------------------------------
27  function word($word=null, $ordinal=null, $region=null, $id=null, $firstword=null, $lastword=null)
28  {
29    if (! is_null($word)) { $this->word = $word; }
30    if (! is_null($ordinal)) { $this->ordinal = $ordinal; }
31    if (! is_null($region)) { $this->region = $region; }
32    if (! is_null($id)) { $this->id = $id; }
33    if (! is_null($firstword)) { $this->firstword = $firstword; }
34    if (! is_null($lastword)) { $this->lastword = $lastword; }
35  }
36
37  // --------------------------------------------------
38  /* given an array of either words or arrays of words which are alternatives at each
39     position, construct a partial query. This creates the last term of the join as a named
40     which shares the same id, and it returns a suitable array of objects to query on */
41  function whereword(&$joiners, $ws, $exact=FALSE, $regions=NULL) {
42    $joiners = array();
43    $wsc = count($ws);
44    $ands = array();
45    for ($i = 0; $i < $wsc; $i++) {
46      $joiners[] = new word();
47      $ors = array();
48      if (is_array($ws[$i])) {
49        foreach ($ws[$i] as $term) {
50          $ors[] = y_op::eq(y_op::field('word',$i), $term);
51        }
52      } else {
53        // single word
54        $ors[] = y_op::eq(y_op::field('word',$i), $ws[$i]);
55      }
56
57      $ands[] = count($ors) == 1 ? $ors[0] : y_op::oor($ors);
58      $ands[] = y_op::feq(y_op::field('id',$wsc),y_op::field('id',$i));
59
60      if ($i > 0) {
61        if (! $exact) {
62          $ands[] = y_op::flt(y_op::field('ordinal', $i-1), y_op::field('ordinal',$i));
63        } else {
64          $ands[] = y_op::oprintf('%f = %f - 1', 
65                                  y_op::field('ordinal', $i-1), y_op::field('ordinal',$i));
66        }
67      }
68    }
69    if ($exact) {
70      // first word of search is first word of result, likewise last
71      $ands[] = y_op::eq(y_op::field('firstword', 0), 1);
72      $ands[] = y_op::eq(y_op::field('lastword', $i-1), 1);
73    }
74
75    if (! empty($regions)) {
76      $ors = array();
77      foreach ($regions as $region) {
78        $ors[] = y_op::eq(y_op::field('region',0), $region);
79      }
80      $ands[] = count($ors) == 1 ? $ors[0] : y_op::oor($ors);
81    }   
82
83    $joiners[] = new named();
84
85    return count($ands) == 1 ? $ands[0] : y_op::aand($ands);
86  }
87
88}
89
90?>
Note: See TracBrowser for help on using the repository browser.