Browse Source

Initial multi-field search page

Experimenting with multi-field search page.
master
Chimo 1 year ago
parent
commit
b3d2fbf7f0

+ 6
- 0
ElasticSearchPlugin.php View File

@@ -48,6 +48,12 @@ class ElasticSearchPlugin extends Plugin
48 48
         }
49 49
     }
50 50
 
51
+    function onRouterInitialized($m)
52
+    {
53
+        // Hijack the regular search page
54
+        $m->connect('search/notice', array('action' => 'enoticesearch'));
55
+    }
56
+
51 57
     function createEngine($target)
52 58
     {
53 59
         $index_name = $this->getIndexname();

+ 143
- 0
actions/enoticesearch.php View File

@@ -0,0 +1,143 @@
1
+<?php
2
+
3
+if (!defined('GNUSOCIAL')) {
4
+    exit(1);
5
+}
6
+
7
+class EnoticesearchAction extends NoticesearchAction
8
+{
9
+    // Same as NoticesearchAction::prepare except we use ElasticSearchNoticeStream
10
+    // instead of SearchNoticeStream so we can pass additional arguments to the search engine.
11
+    function prepare(array $args = array())
12
+    {
13
+        // We don't want parent::prepare() because then it'll use the original
14
+        // `SearchNoticeStream` class
15
+        Action::prepare($args);
16
+
17
+        $this->q = $this->trimmed('q');
18
+        $this->author = $this->trimmed('author');
19
+        $this->type = $this->trimmed('type');
20
+        $this->created = $this->trimmed('created');
21
+
22
+        if (preg_match('/^#([\pL\pN_\-\.]{1,64})/ue', $this->q)) {
23
+            common_redirect(common_local_url('tag',
24
+                                             array('tag' => common_canonical_tag(substr($this->q, 1)))),
25
+                            303);
26
+        }
27
+
28
+        if (!empty($this->q)) {
29
+            $stream  = new ElasticSearchNoticeStream(
30
+                                $this->q,
31
+                                $this->scoped,
32
+                                $this->author,
33
+                                $this->type,
34
+                                $this->created
35
+                            );
36
+
37
+            $page    = $this->trimmed('page');
38
+
39
+            if (empty($page)) {
40
+                $page = 1;
41
+            } else {
42
+                $page = (int)$page;
43
+            }
44
+
45
+            $this->notice = $stream->getNotices((($page-1)*NOTICES_PER_PAGE), NOTICES_PER_PAGE + 1);
46
+        }
47
+
48
+        common_set_returnto($this->selfUrl());
49
+
50
+        return true;
51
+    }
52
+
53
+    function getInstructions()
54
+    {
55
+        // pass, for now
56
+    }
57
+
58
+    // Based on searchaction.php::showForm()
59
+    function showForm($error=null)
60
+    {
61
+        $q = $this->trimmed('q');
62
+        $author = $this->trimmed('author');
63
+        $type = $this->trimmed('type');
64
+        $created = $this->trimmed('created');
65
+
66
+        $page = $this->trimmed('page', 1);
67
+
68
+        $this->elementStart('form', array('method' => 'get',
69
+                                           'id' => 'form_search',
70
+                                           'class' => 'form_settings',
71
+                                           'action' => common_local_url($this->trimmed('action'))));
72
+
73
+        $this->elementStart('fieldset');
74
+        $this->element('legend', null, _('Search site'));
75
+        $this->elementStart('ul', 'form_data');
76
+        $this->elementStart('li');
77
+        if (!common_config('site', 'fancy')) {
78
+            $this->hidden('action', $this->trimmed('action'));
79
+        }
80
+
81
+        // Notice content
82
+        $this->input('q', 'Notice text', $q);
83
+        $this->elementEnd('li');
84
+
85
+        // Notice author
86
+        $this->elementStart('li');
87
+        $this->input(
88
+            'author',
89
+            'Author',
90
+            $author,
91
+            null,
92
+            null,
93
+            false,
94
+            array('placeholder' => 'user@example.org')
95
+        );
96
+        $this->elementEnd('li');
97
+
98
+        // Notice type
99
+        $this->elementStart('li');
100
+        $this->dropdown(
101
+            'type',
102
+            'Notice type',
103
+            array(
104
+                'post' => 'post',
105
+                'share' => 'repeat',
106
+                'reply' => 'comment'
107
+            ),
108
+            null,
109
+            true,
110
+            $type
111
+        );
112
+        $this->elementEnd('li');
113
+
114
+/* not ready yet...
115
+
116
+        // Notice created date
117
+        $this->elementStart('li');
118
+        $this->input('created', 'Date created', null, null, null, false, array('type' => 'date'));
119
+        $this->elementEnd('li');
120
+*/
121
+
122
+        $this->element('input', array('type'=>'submit', 'class'=>'submit', 'value'=>_m('BUTTON','Search')));
123
+        $this->elementEnd('li');
124
+        $this->elementEnd('ul');
125
+        $this->elementEnd('fieldset');
126
+        $this->elementEnd('form');
127
+
128
+        if ($q) {
129
+            $this->showResults($q, $page);
130
+        }
131
+    }
132
+
133
+    function showNoticeForm()
134
+    {
135
+        // pass
136
+    }
137
+
138
+    function showProfileBlock()
139
+    {
140
+        // pass
141
+    }
142
+}
143
+

+ 12
- 0
classes/ElasticSearchNoticeStream.php View File

@@ -0,0 +1,12 @@
1
+<?php
2
+
3
+if (!defined('GNUSOCIAL')) { exit(1); }
4
+
5
+class ElasticSearchNoticeStream extends ScopingNoticeStream
6
+{
7
+    function __construct($q, Profile $scoped=null, $author, $type, $created)
8
+    {
9
+        parent::__construct(new RawElasticSearchNoticeStream($q, $author, $type, $created), $scoped);
10
+    }
11
+}
12
+

+ 43
- 0
classes/RawElasticSearchNoticeStream.php View File

@@ -0,0 +1,43 @@
1
+<?php
2
+
3
+if (!defined('GNUSOCIAL')) { exit(1); }
4
+
5
+require_once INSTALLDIR . '/lib/searchnoticestream.php';
6
+
7
+class RawElasticSearchNoticeStream extends RawSearchNoticeStream
8
+{
9
+    protected $q;
10
+    protected $author;
11
+    protected $type;
12
+    protected $created;
13
+
14
+    function __construct($q, $author, $type, $created)
15
+    {
16
+        $this->q = $q;
17
+        $this->author = $author;
18
+        $this->type = $type;
19
+        $this->created = $created;
20
+    }
21
+
22
+    function getNoticeIds($offset, $limit, $since_id, $max_id)
23
+    {
24
+        $notice = new Notice();
25
+
26
+        $search_engine = $notice->getSearchEngine('notice');
27
+        $search_engine->set_sort_mode('chron');
28
+        $search_engine->limit($offset, $limit);
29
+
30
+        $ids = array();
31
+
32
+        $search_engine->esQuery($this->q, $this->author, $this->type, $this->created);
33
+
34
+        if ($notice->find()) {
35
+            while ($notice->fetch()) {
36
+                $ids[] = $notice->id;
37
+            }
38
+        }
39
+
40
+        return $ids;
41
+    }
42
+}
43
+

+ 35
- 15
lib/ElasticSearch.php View File

@@ -38,16 +38,16 @@ class ElasticSearch extends SearchEngine
38 38
             if ($index_suffix === 'notice') {
39 39
                 $props = [
40 40
                     'author' => [
41
-                        'type' => 'string'
41
+                        'type' => 'keyword'
42 42
                     ],
43 43
                     'text' => [
44
-                        'type' => 'string'
44
+                        'type' => 'text'
45 45
                     ],
46 46
                     'verb' => [
47
-                        'type' => 'string'
47
+                        'type' => 'keyword'
48 48
                     ],
49 49
                     'type' => [
50
-                        'type' => 'string'
50
+                        'type' => 'keyword'
51 51
                     ],
52 52
                     'created' => [
53 53
                         'type' => 'date',
@@ -57,16 +57,16 @@ class ElasticSearch extends SearchEngine
57 57
             } else { // 'profile'
58 58
                 $props = [
59 59
                     'nickname' => [
60
-                        'type' => 'string'
60
+                        'type' => 'text'
61 61
                     ],
62 62
                     'fullname' => [
63
-                        'type' => 'string'
63
+                        'type' => 'text'
64 64
                     ],
65 65
                     'bio' => [
66
-                        'type' => 'string'
66
+                        'type' => 'text'
67 67
                     ],
68 68
                     'location' => [
69
-                        'type' => 'string'
69
+                        'type' => 'text'
70 70
                     ],
71 71
                     'created' => [
72 72
                         'type' => 'date',
@@ -251,7 +251,7 @@ class ElasticSearch extends SearchEngine
251 251
     }
252 252
 
253 253
     // From SearchEngine class
254
-    function query($q)
254
+    function esQuery($q, $author, $type, $created)
255 255
     {
256 256
         $default_field = 'text';
257 257
 
@@ -259,16 +259,36 @@ class ElasticSearch extends SearchEngine
259 259
             $default_field = 'nickname';
260 260
         }
261 261
 
262
+        $query = [
263
+            'bool' => [
264
+                'must' => [],
265
+                'filter' => []
266
+            ],
267
+        ];
268
+
269
+        if ($q) {
270
+            $query['bool']['must'][] = [
271
+                'match' => ['text' => $q]
272
+            ];
273
+        }
274
+
275
+        if ($author) {
276
+            $query['bool']['filter'][] = [
277
+                'term' => ['author' => $author]
278
+            ];
279
+        }
280
+
281
+        if ($type) {
282
+            $query['bool']['filter'][] = [
283
+                'term' => ['verb' => $type]
284
+            ];
285
+        }
286
+
262 287
         $params = [
263 288
             'index' => $this->index_name,
264 289
             'type' => $this->index_type,
265 290
             'body' => [
266
-                'query' => [
267
-                    'query_string' => [
268
-                        'default_field' => $default_field,
269
-                        'query' => $q
270
-                    ]
271
-                ]
291
+                'query' => $query
272 292
             ]
273 293
         ];
274 294
 

Loading…
Cancel
Save