Skip to content

Commit 02c6030

Browse files
committed
Proof of concept Search WebApp to show how to implement doc. search
This adds the Proof of concept WebApp to show how to glue together the Solr search platform with COOL server with "convert-to" and "render-search-result" REST services and combine everything into a document search solution. Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> Change-Id: Iea3a2f6e2afee090bc7a27648390025d2a8c94d8
1 parent b31eb2a commit 02c6030

File tree

9 files changed

+422
-0
lines changed

9 files changed

+422
-0
lines changed

indexing/Docs/About LibreoOffice.odt

33.8 KB
Binary file not shown.

indexing/Docs/Lorem.odt

19.7 KB
Binary file not shown.

indexing/Docs/ODTTestFile.odt

33.4 KB
Binary file not shown.
72 KB
Binary file not shown.

indexing/Docs/SimpleSample.odt

37.3 KB
Binary file not shown.

indexing/Main.html

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!DOCTYPE html>
2+
<html lang="en" ng-app="SearchApp">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>Search - Proof of Concept</title>
8+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
9+
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
10+
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular-resource.min.js"></script>
11+
<script src="Main.js"></script>
12+
</head>
13+
14+
<body ng-controller="SearchMainController">
15+
<div class="container">
16+
<div class="row">
17+
<div class="col">
18+
<form class="row g-1 justify-content-md-center">
19+
<div class="col-sm-6">
20+
<input class="form-control" type="text" ng-model="searchString" placeholder="Search string..." >
21+
</div>
22+
<div class="col-auto">
23+
<button type="button" ng-click="searchClicked()" ng-disabled="searchDisabled()" class="btn btn-primary mb-3">Search</button>
24+
</div>
25+
<div class="col-auto">
26+
<button type="button" ng-click="reindexClicked()" class="btn btn-primary">Re-index Documents</button>
27+
</div>
28+
</form>
29+
</div>
30+
</div>
31+
<div class="row" ng-show="searchResult.length > 0">
32+
<div class="col"><b>Search Result</b></div>
33+
<table class="table table-vcenter table-striped table-hover table-bordered">
34+
<thead>
35+
<tr>
36+
<th class="col-xs-6">Filename</th>
37+
<th class="col-xs-6">Image</th>
38+
</tr>
39+
</thead>
40+
<tbody>
41+
<tr>
42+
<tr class="table-repeat" ng-repeat="result in searchResult">
43+
<td><a href="{{result.href}}">{{result.filename}}</td>
44+
<td><img data-ng-src="data:image/png;base64,{{result.image}}"/></td>
45+
</tr>
46+
</tbody>
47+
</table>
48+
<button type="button" ng-click="clearSearchResults()" class="btn btn-primary">Clear</button>
49+
</div>
50+
<div class="row" ng-show="searchResult.length == 0">
51+
<table class="table table-vcenter table-striped table-hover table-bordered">
52+
<thead>
53+
<tr>
54+
<th class="col-xs-6">Filename</th>
55+
</tr>
56+
</thead>
57+
<tbody>
58+
<tr>
59+
<tr class="table-repeat" ng-repeat="document in documents">
60+
<td><a href="{{document.href}}">{{document.name}}</a></td>
61+
</tr>
62+
</tbody>
63+
</table>
64+
</div>
65+
<div class="row">
66+
<p>Status: {{status}}</p>
67+
</div>
68+
</div>
69+
</body>
70+
</html>

indexing/Main.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
var searchApp = angular.module('SearchApp', ['ngResource']);
2+
3+
searchApp.factory('SearchAPI', ['$http',
4+
function ($http) {
5+
return {
6+
getDocuments: function () {
7+
var promise = $http.get('/documents').then(function(response) {
8+
return response.data;
9+
}, function (error) {
10+
return [];
11+
})
12+
return promise;
13+
},
14+
reindexDocuments: function () {
15+
var promise = $http.post('/reindex').then(function(response) {
16+
return true;
17+
}, function (error) {
18+
return false;
19+
})
20+
return promise;
21+
},
22+
search: function (query) {
23+
var queryJson = { "query" : query };
24+
var promise = $http.post('/search', queryJson).then(function(response) {
25+
return response.data;
26+
}, function (error) {
27+
return null;
28+
})
29+
return promise;
30+
},
31+
getResultImage: function(jsonResult) {
32+
var promise = $http.post('/image', jsonResult).then(function(response) {
33+
return response.data;
34+
}, function (error) {
35+
return null;
36+
})
37+
return promise;
38+
}
39+
}
40+
}
41+
]);
42+
43+
searchApp.controller('SearchMainController', ['$scope', 'SearchAPI', function($scope, SearchAPI) {
44+
45+
$scope.searchResult = []
46+
47+
$scope.searchString = "";
48+
$scope.status = "Ready";
49+
50+
$scope.reindexClicked = function() {
51+
$scope.status = "Reindexing....";
52+
53+
SearchAPI.reindexDocuments().then(function(data) {
54+
$scope.status = "Finished reindexing";
55+
});
56+
};
57+
58+
$scope.clearSearchResults = function() {
59+
$scope.searchResult = []
60+
}
61+
62+
$scope.searchClicked = function() {
63+
$scope.searchResult = []
64+
SearchAPI.search($scope.searchString).then(function(jsonResult) {
65+
$scope.status = "Search finished " + jsonResult.length;
66+
for (let i = 0; i < jsonResult.length; i++) {
67+
let result = jsonResult[i];
68+
$scope.searchResult[i] = result;
69+
SearchAPI.getResultImage(result).then(function(image) {
70+
result.image = image;
71+
});
72+
}
73+
});
74+
75+
$scope.status = "Searching... " + $scope.searchString;
76+
};
77+
78+
$scope.searchDisabled = function() {
79+
return $scope.searchString == "";
80+
};
81+
82+
$scope.documents = []
83+
84+
SearchAPI.getDocuments().then(function(data) {
85+
$scope.documents = data;
86+
});
87+
88+
$scope.documentSize = function() {
89+
return $scope.documents.length;
90+
};
91+
92+
}]);
93+

indexing/README

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Searching and indexing example APP
2+
**********************************
3+
4+
Main.js and Main.html - HTML/JS client side
5+
Server.py - HTTP Server and server side processing via. REST API
6+
7+
Configuration
8+
*************
9+
10+
Open "Server.py" and change the COOL and Solr server URL ("coolServerUrl" and "solrServerUrl") if they are different
11+
than localhost and default ports.
12+
13+
The "documentPath" constant is the root location of the documents (relative where Server.py was started).
14+
15+
The "solrCollectionName" constant is the collection name where Solr should store the indices.
16+
17+
The "coolInstance" is the URL to the COOL instance, which is used to open a document.
18+
19+
The collection needs to be created in Solr, if it doesn't yet exists with (from Solr root):
20+
./bin/solr create -c <collection name>
21+
22+
For exmaple:
23+
./bin/solr create -c documents
24+
25+
HTTP Server
26+
***********
27+
28+
Run http server on locally with:
29+
"python Server.py 8000 127.0.0.1"
30+
31+
Then connect from the web browser to "http::/localhost:8000"
32+
33+
First time - run "Re-Index Documents" or nothing will be found

0 commit comments

Comments
 (0)