-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PoC to integrate the Vectara search engine (#128)
* This introduces Vectara. * Not perfect but it does work. --------- Co-authored-by: Eric Pugh <[email protected]>
- Loading branch information
Showing
11 changed files
with
517 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
'use strict'; | ||
|
||
/*jslint latedef:false*/ | ||
|
||
(function() { | ||
angular.module('o19s.splainer-search') | ||
.factory('VectaraDocFactory', [ | ||
'vectaraUrlSvc', | ||
'DocFactory', | ||
VectaraDocFactory | ||
]); | ||
|
||
function VectaraDocFactory(vectaraUrlSvc, DocFactory) { | ||
const Doc = function(doc, options) { | ||
DocFactory.call(this, doc, options); | ||
|
||
const self = this; | ||
|
||
angular.forEach(self.fieldsProperty(), function(fieldValue, fieldName) { | ||
if ( fieldValue !== null && fieldValue.constructor === Array && fieldValue.length === 1 ) { | ||
self[fieldName] = fieldValue[0]; | ||
} else { | ||
self[fieldName] = fieldValue; | ||
} | ||
}); | ||
}; | ||
|
||
Doc.prototype = Object.create(DocFactory.prototype); | ||
Doc.prototype.constructor = Doc; // Reset the constructor | ||
Doc.prototype._url = _url; | ||
Doc.prototype.origin = origin; | ||
Doc.prototype.fieldsProperty = fieldsProperty; | ||
Doc.prototype.explain = explain; | ||
Doc.prototype.snippet = snippet; | ||
Doc.prototype.highlight = highlight; | ||
|
||
|
||
function _url () { | ||
return 'unavailable'; | ||
} | ||
|
||
function origin () { | ||
/*jslint validthis:true*/ | ||
var self = this; | ||
|
||
var src = {}; | ||
angular.forEach(self, function(value, field) { | ||
if (!angular.isFunction(value)) { | ||
src[field] = value; | ||
} | ||
}); | ||
delete src.doc; | ||
delete src.metadata; | ||
delete src.opts; | ||
return src; | ||
} | ||
|
||
function fieldsProperty() { | ||
/*jslint validthis:true*/ | ||
const self = this; | ||
const metadata = self.metadata; | ||
return metadata.reduce(function(map, obj) { | ||
map[obj.name] = obj.value; | ||
return map; | ||
}, {}); | ||
} | ||
|
||
function explain () { | ||
// no explain functionality implemented | ||
return {}; | ||
} | ||
|
||
function snippet () { | ||
// no snippet functionality implemented | ||
return null; | ||
} | ||
|
||
function highlight () { | ||
// no highlighting functionality implemented | ||
return null; | ||
} | ||
|
||
return Doc; | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
'use strict'; | ||
|
||
/*jslint latedef:false*/ | ||
|
||
(function() { | ||
angular.module('o19s.splainer-search') | ||
.factory('VectaraSearcherFactory', [ | ||
'$http', | ||
'$q', | ||
'$log', | ||
'VectaraDocFactory', | ||
'activeQueries', | ||
'vectaraSearcherPreprocessorSvc', | ||
'vectaraUrlSvc', | ||
'SearcherFactory', | ||
'transportSvc', | ||
VectaraSearcherFactory | ||
]); | ||
|
||
function VectaraSearcherFactory( | ||
$http, $q, $log, | ||
VectaraDocFactory, | ||
activeQueries, | ||
vectaraSearcherPreprocessorSvc, | ||
vectaraUrlSvc, | ||
SearcherFactory, | ||
transportSvc | ||
) { | ||
|
||
var Searcher = function(options) { | ||
SearcherFactory.call(this, options, vectaraSearcherPreprocessorSvc); | ||
}; | ||
|
||
Searcher.prototype = Object.create(SearcherFactory.prototype); | ||
Searcher.prototype.constructor = Searcher; // Reset the constructor | ||
|
||
Searcher.prototype.addDocToGroup = addDocToGroup; | ||
Searcher.prototype.pager = pager; | ||
Searcher.prototype.search = search; | ||
|
||
|
||
function addDocToGroup (groupedBy, group, vectaraDoc) { | ||
/*jslint validthis:true*/ | ||
const self = this; | ||
|
||
if (!self.grouped.hasOwnProperty(groupedBy)) { | ||
self.grouped[groupedBy] = []; | ||
} | ||
|
||
var found = null; | ||
angular.forEach(self.grouped[groupedBy], function(groupedDocs) { | ||
if (groupedDocs.value === group && !found) { | ||
found = groupedDocs; | ||
} | ||
}); | ||
|
||
if (!found) { | ||
found = {docs:[], value:group}; | ||
self.grouped[groupedBy].push(found); | ||
} | ||
|
||
found.docs.push(vectaraDoc); | ||
} | ||
|
||
// return a new searcher that will give you | ||
// the next page upon search(). To get the subsequent | ||
// page, call pager on that searcher | ||
function pager (){ | ||
/*jslint validthis:true*/ | ||
const self = this; | ||
let pagerArgs = {}; | ||
let nextArgs = angular.copy(self.args); | ||
|
||
if (nextArgs.hasOwnProperty('pager') && nextArgs.pager !== undefined) { | ||
pagerArgs = nextArgs.pager; | ||
} else if (self.hasOwnProperty('pagerArgs') && self.pagerArgs !== undefined) { | ||
pagerArgs = self.pagerArgs; | ||
} | ||
|
||
if (pagerArgs.hasOwnProperty('from')) { | ||
pagerArgs.from = parseInt(pagerArgs.from) + pagerArgs.size; | ||
|
||
if (pagerArgs.from >= self.numFound) { | ||
return null; // no more results | ||
} | ||
} else { | ||
pagerArgs.from = pagerArgs.size; | ||
} | ||
|
||
nextArgs.pager = pagerArgs; | ||
var options = { | ||
args: nextArgs, | ||
config: self.config, | ||
fieldList: self.fieldList, | ||
queryText: self.queryText, | ||
type: self.type, | ||
url: self.url, | ||
}; | ||
|
||
return new Searcher(options); | ||
} | ||
|
||
// search (execute the query) and produce results | ||
// to the returned future | ||
function search () { | ||
/*jslint validthis:true*/ | ||
const self= this; | ||
var apiMethod = 'POST'; | ||
var url = self.url; | ||
var transport = transportSvc.getTransport({apiMethod: apiMethod}); | ||
|
||
var queryDslWithPagerArgs = angular.copy(self.queryDsl); | ||
if (self.pagerArgs) { | ||
queryDslWithPagerArgs.from = self.pagerArgs.from; | ||
queryDslWithPagerArgs.size = self.pagerArgs.size; | ||
} | ||
|
||
self.inError = false; | ||
|
||
const headers = vectaraUrlSvc.getHeaders(self.config.customHeaders); | ||
|
||
activeQueries.count++; | ||
return transport.query(url, queryDslWithPagerArgs, headers) | ||
.then(function success(httpConfig) { | ||
var data = httpConfig.data; | ||
activeQueries.count--; | ||
|
||
const documents = data.responseSet && data.responseSet.length > 0 ? data.responseSet[0].document : []; | ||
|
||
self.numFound = documents.length; | ||
|
||
var parseDoc = function(doc, groupedBy, group) { | ||
var options = { | ||
groupedBy: groupedBy, | ||
group: group, | ||
fieldList: self.fieldList, | ||
url: self.url | ||
}; | ||
|
||
return new VectaraDocFactory(doc, options); | ||
}; | ||
|
||
angular.forEach(documents, function(docFromApi) { | ||
const doc = parseDoc(docFromApi); | ||
self.docs.push(doc); | ||
}); | ||
|
||
}, function error(msg) { | ||
activeQueries.count--; | ||
self.inError = true; | ||
msg.searchError = 'Error with Vectara query or server. Review request manually.'; | ||
return $q.reject(msg); | ||
}) | ||
.catch(function(response) { | ||
$log.debug('Failed to execute search'); | ||
return $q.reject(response); | ||
}); | ||
} // end of search() | ||
|
||
// Return factory object | ||
return Searcher; | ||
} | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "splainer-search", | ||
"version": "2.24.0", | ||
"version": "2.25.0", | ||
"main": "splainer-search.js", | ||
"authors": [ | ||
"Doug Turnbull <[email protected]>", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.