/
SearchQuery.php
152 lines (128 loc) · 4.28 KB
/
SearchQuery.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
/**
* Represents a search query
*
* API very much still in flux.
*/
class SearchQuery extends ViewableData
{
public static $missing = null;
public static $present = null;
public static $default_page_size = 10;
/** These are public, but only for index & variant access - API users should not manually access these */
public $search = array();
public $classes = array();
public $require = array();
public $exclude = array();
protected $start = 0;
protected $limit = -1;
/** These are the API functions */
public function __construct()
{
if (self::$missing === null) {
self::$missing = new stdClass();
}
if (self::$present === null) {
self::$present = new stdClass();
}
}
/**
* @param String $text Search terms. Exact format (grouping, boolean expressions, etc.) depends on the search implementation.
* @param array $fields Limits the search to specific fields (using composite field names)
* @param array $boost Map of composite field names to float values. The higher the value,
* the more important the field gets for relevancy.
*/
public function search($text, $fields = null, $boost = array())
{
$this->search[] = array('text' => $text, 'fields' => $fields ? (array)$fields : null, 'boost' => $boost, 'fuzzy' => false);
}
/**
* Similar to {@link search()}, but uses stemming and other similarity algorithms
* to find the searched terms. For example, a term "fishing" would also likely find results
* containing "fish" or "fisher". Depends on search implementation.
*
* @param String $text See {@link search()}
* @param array $fields See {@link search()}
* @param array $boost See {@link search()}
*/
public function fuzzysearch($text, $fields = null, $boost = array())
{
$this->search[] = array('text' => $text, 'fields' => $fields ? (array)$fields : null, 'boost' => $boost, 'fuzzy' => true);
}
public function inClass($class, $includeSubclasses = true)
{
$this->classes[] = array('class' => $class, 'includeSubclasses' => $includeSubclasses);
}
/**
* Similar to {@link search()}, but typically used to further narrow down
* based on other facets which don't influence the field relevancy.
*
* @param String $field Composite name of the field
* @param Mixed $values Scalar value, array of values, or an instance of SearchQuery_Range
*/
public function filter($field, $values)
{
$requires = isset($this->require[$field]) ? $this->require[$field] : array();
$values = is_array($values) ? $values : array($values);
$this->require[$field] = array_merge($requires, $values);
}
/**
* Excludes results which match these criteria, inverse of {@link filter()}.
*
* @param String $field
* @param mixed $values
*/
public function exclude($field, $values)
{
$excludes = isset($this->exclude[$field]) ? $this->exclude[$field] : array();
$values = is_array($values) ? $values : array($values);
$this->exclude[$field] = array_merge($excludes, $values);
}
public function start($start)
{
$this->start = $start;
}
public function limit($limit)
{
$this->limit = $limit;
}
public function page($page)
{
$this->start = $page * self::$default_page_size;
$this->limit = self::$default_page_size;
}
public function isfiltered()
{
return $this->search || $this->classes || $this->require || $this->exclude;
}
public function __toString()
{
return "Search Query\n";
}
}
/**
* Create one of these and pass as one of the values in filter or exclude to filter or exclude by a (possibly
* open ended) range
*/
class SearchQuery_Range
{
public $start = null;
public $end = null;
public function __construct($start = null, $end = null)
{
$this->start = $start;
$this->end = $end;
}
public function start($start)
{
$this->start = $start;
}
public function end($end)
{
$this->end = $end;
}
public function isfiltered()
{
return $this->start !== null || $this->end !== null;
}
}