root/solr/files/lib/data/solr/SolrBridge.php @ 1185

Revision 1185, 5.1 kB (checked in by d0nut, 3 years ago)

it is possible to display solr status :)

Line 
1<?php
2// wcf imports
3require_once(WCF_DIR.'lib/data/message/search/SearchEngine.class.php');
4require_once(WCF_DIR.'lib/data/solr/SolrService.php');
5
6
7/**
8 *
9 */     
10class SolrBridge {
11       
12        /**
13         *
14         * @var array<Apache_Solr_Document>
15         */
16        protected $documents = array();
17       
18        /**
19         *
20         * @var SolrService
21         */
22        protected $solr = null;
23       
24        /**
25         *
26         */
27        public function __construct() {
28       
29                // load search type objects
30                SearchEngine::getSearchTypes();
31               
32                $this->solr = new SolrService();
33        }
34       
35        /**
36         *
37         */
38        protected function commit() {
39                $this->solr->addDocuments( $this->documents );
40                $this->solr->commit();
41               
42                // mark items as done
43                $sql = "INSERT IGNORE INTO
44                                        wcf".WCF_N."_solr_index
45                                        (typeID, messageID)";
46                foreach($this->documents as $doc) {
47                        $sql .= ""; //TODO: mark as done
48                }
49                $result = WCF::getDB()->sendQuery($sql);
50               
51                // reset array
52                $this->documents = array();
53               
54                $this->solr->optimize();
55        }
56       
57        /**
58         *
59         */
60        protected function getTotals(array $types, $func) {
61
62                $sql = '';
63                foreach ($types as $type) {
64
65                        // get search type object
66                        $doc = SearchEngine::$searchTypeObjects[$type];
67                        if (!$doc->isAccessible()) continue;
68                        if (!empty($sql)) $sql .= "\nUNION\n";
69                       
70                        // get field names
71                        $messageIDFieldName = $doc->getIDFieldName();
72                        $messageIDFieldName = strpos($messageIDFieldName, '.') !== false ? $messageIDFieldName : "messageTable.".$messageIDFieldName;
73                       
74                        $sql .= "(     
75                                SELECT          ".$func."(".$messageIDFieldName.") AS messageID,
76                                                '".$type."' AS messageType
77                                FROM            ".$doc->getTableName()." messageTable
78                                                ".$doc->getJoins()."
79                        )";
80                }
81               
82                // send search query
83                $types = array();
84                $result = WCF::getDB()->sendQuery($sql);
85                while ($row = WCF::getDB()->fetchArray($result)) {
86                        $types[$row['messageType']] = $row['messageID'];
87                }
88               
89                return $types;
90        }
91       
92        /**
93         *
94         */
95        public function loadDocuments($type, $min, $max) {
96                // get search type object
97                $doc = SearchEngine::$searchTypeObjects[$type];
98                if (!$doc->isAccessible()) continue;
99               
100                // get field names
101                $messageIDFieldName = $doc->getIDFieldName();
102                $messageIDFieldName = strpos($messageIDFieldName, '.') !== false ? $messageIDFieldName : "messageTable.".$messageIDFieldName;
103                $subjectFieldNames = $doc->getSubjectFieldNames();
104                $messageFieldNames = $doc->getMessageFieldNames();
105                $userIDFieldName = $doc->getUserIDFieldName();
106                $usernameFieldName = $doc->getUsernameFieldName();
107                $timeFieldName = $doc->getTimeFieldName();
108               
109                $sql = "SELECT         
110                                        '".$type."' AS messageType,
111                                        ".$messageIDFieldName." AS messageID,
112                                        CAST(messageTable.".reset($subjectFieldNames)." AS CHAR CHARACTER SET ".WCF::getDB()->getCharset().") AS subject,
113                                        CAST(messageTable.".reset($messageFieldNames)." AS CHAR CHARACTER SET ".WCF::getDB()->getCharset().") AS message,
114                                        ".$userIDFieldName." AS userID,
115                                        CAST(".$usernameFieldName." AS CHAR CHARACTER SET ".WCF::getDB()->getCharset().") AS username,
116                                        ".$timeFieldName." AS time
117                        FROM            ".$doc->getTableName()." messageTable
118                                        ".$doc->getJoins()."
119                        WHERE           ".$messageIDFieldName." BETWEEN $min AND $max
120                                        ".(!empty($conditions[$type]) ? " ".(!empty($q) ? "AND" : "")." (".$conditions[$type].")" : "")."
121                        GROUP BY        messageID";
122
123                $result = WCF::getDB()->sendQuery($sql, $limit);
124                while ($row = WCF::getDB()->fetchArray($result)) {
125                        $this->addDocument($row);
126                }
127        }
128       
129        /**
130         *
131         */
132        protected function addDocument($fields) {
133                $part = new Apache_Solr_Document();
134                foreach ( $fields as $key => $value ) {
135                        if ( is_array( $value ) ) {
136                                foreach ( $value as $deppval ) {
137                                        $part->setMultiValue( $key, $deppval );
138                                }
139                        }
140                        else {
141                                $part->$key = $value;
142                        }
143                }
144               
145                $this->documents[] = $part;
146        }
147       
148        /**
149         *
150         */
151        public function doCrawl($types, $limit) {
152                foreach($this->getIndexStatus($types) as $typeName => $status) {
153               
154                        // nothing to do?
155                        if($row['total'] == $row['current']) {
156                                continue;
157                        }
158                       
159                        if (!isset(SearchEngine::$searchTypeObjects[$type])) {
160                                throw new SystemException('unknown search type '.$type, 101001);
161                        }
162                       
163                        $this->loadDocuments($row['current'] + 1, min($row['total'], $row['current'] + 1 + $limit));
164
165                        // write to solr
166                        $this->commit();
167                }
168        }
169       
170        /**
171         *
172         */
173        public function getIndexStatus($types = null) {
174               
175                // read available types
176                $status = array();
177               
178                // get types
179                $types = is_array($types) ? $types : SearchEngine::getSearchTypes();
180               
181                // set counters to zero
182                foreach ($types as $type) {
183                        $status[$type] = array(
184                                'current' => 0,
185                                'total' => 0,
186                                'percent' => 0,
187                        );
188                }
189               
190                // read current status
191                $sql = 'SELECT          typeName,
192                                        c
193                        FROM (
194                                SELECT          typeID,
195                                                COUNT(typeID) AS c
196                                FROM            wcf'.WCF_N.'_solr_index
197                                GROUP BY        typeID
198                        ) x
199                        INNER JOIN      wcf'.WCF_N.'_searchable_message_type USING(typeID)';
200                while ($row = WCF::getDB()->fetchArray($sql)) {
201                        $typeName = $row['typeName'];
202                        $status[$typeName]['current'] = $row['c'];
203                }
204
205                // read totals
206                foreach ($this->getTotals($types, 'COUNT') as $typeName => $count) {
207                        $percent = $count ? 100 / $count * $status[$typeName]['current'] : 0;
208                        $status[$typeName]['total'] = $count;
209                }
210               
211                return $status;
212        }
213}
214?>
Note: See TracBrowser for help on using the browser.