-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
391 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"IsEncrypted": false, | ||
"Values": { | ||
"AzureWebJobsStorage": "", | ||
"FUNCTIONS_WORKER_RUNTIME": "node", | ||
"SearchApiKey": "9kPbP52tyc6HFhS7ZJb8xmmkMjB5iK1dYKjY4bpSuUAzSeD3aLJ9", | ||
"SearchServiceName": "govsearch", | ||
"SearchIndexName": "azureblob-index", | ||
"SearchFacets": "people*,organizations*,locations*", | ||
} | ||
} |
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,20 @@ | ||
{ | ||
"bindings": [ | ||
{ | ||
"authLevel": "anonymous", | ||
"type": "httpTrigger", | ||
"direction": "in", | ||
"name": "req", | ||
"methods": [ | ||
"get", | ||
"post" | ||
], | ||
"route": "search" | ||
}, | ||
{ | ||
"type": "http", | ||
"direction": "out", | ||
"name": "res" | ||
} | ||
] | ||
} |
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,115 @@ | ||
const { SearchClient, AzureKeyCredential } = require("@azure/search-documents"); | ||
|
||
const indexName = process.env["SearchIndexName"]; | ||
const apiKey = process.env["SearchApiKey"]; | ||
const searchServiceName = process.env["SearchServiceName"]; | ||
|
||
// Create a SearchClient to send queries | ||
const client = new SearchClient( | ||
`https://` + searchServiceName + `.search.windows.net/`, | ||
indexName, | ||
new AzureKeyCredential(apiKey) | ||
); | ||
|
||
// creates filters in odata syntax | ||
const createFilterExpression = (filterList, facets) => { | ||
let i = 0; | ||
let filterExpressions = []; | ||
|
||
while (i < filterList.length) { | ||
let field = filterList[i].field; | ||
let value = filterList[i].value; | ||
|
||
if (facets[field] === 'array') { | ||
filterExpressions.push(`${field}/any(t: search.in(t, '${value}', ','))`); | ||
} else { | ||
filterExpressions.push(`${field} eq '${value}'`); | ||
} | ||
i += 1; | ||
} | ||
|
||
return filterExpressions.join(' and '); | ||
} | ||
|
||
// reads in facets and gets type | ||
// array facets should include a * at the end | ||
// this is used to properly create filters | ||
const readFacets = (facetString) => { | ||
let facets = facetString.split(","); | ||
let output = {}; | ||
facets.forEach(function (f) { | ||
if (f.indexOf('*') > -1) { | ||
output[f.replace('*', '')] = 'array'; | ||
} else { | ||
output[f] = 'string'; | ||
} | ||
}) | ||
|
||
return output; | ||
} | ||
|
||
module.exports = async function (context, req) { | ||
|
||
//context.log(req); | ||
|
||
try { | ||
// Reading inputs from HTTP Request | ||
let q = (req.query.q || (req.body && req.body.q)); | ||
const top = (req.query.top || (req.body && req.body.top)); | ||
const skip = (req.query.skip || (req.body && req.body.skip)); | ||
const filters = (req.query.filters || (req.body && req.body.filters)); | ||
const facets = readFacets(process.env["SearchFacets"]); | ||
|
||
|
||
// If search term is empty, search everything | ||
if (!q || q === "") { | ||
q = "*"; | ||
} | ||
|
||
// Creating SearchOptions for query | ||
let searchOptions = { | ||
top: top, | ||
skip: skip, | ||
includeTotalCount: true, | ||
facets: Object.keys(facets), | ||
filter: createFilterExpression(filters, facets) | ||
}; | ||
|
||
// Sending the search request | ||
const searchResults = await client.search(q, searchOptions); | ||
|
||
// Getting results for output | ||
const output = []; | ||
for await (const result of searchResults.results) { | ||
output.push(result); | ||
} | ||
|
||
// Logging search results | ||
context.log(searchResults.count); | ||
|
||
// Creating the HTTP Response | ||
context.res = { | ||
// status: 200, /* Defaults to 200 */ | ||
headers: { | ||
"Content-type": "application/json" | ||
}, | ||
body: { | ||
count: searchResults.count, | ||
results: output, | ||
facets: searchResults.facets | ||
} | ||
}; | ||
} catch (error) { | ||
context.log.error(error); | ||
|
||
// Creating the HTTP Response | ||
context.res = { | ||
status: 400, | ||
body: { | ||
innerStatusCode: error.statusCode || error.code, | ||
error: error.details || error.message | ||
} | ||
}; | ||
} | ||
|
||
}; |
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,20 @@ | ||
{ | ||
"bindings": [ | ||
{ | ||
"authLevel": "anonymous", | ||
"type": "httpTrigger", | ||
"direction": "in", | ||
"name": "req", | ||
"methods": [ | ||
"get", | ||
"post" | ||
], | ||
"route": "suggest" | ||
}, | ||
{ | ||
"type": "http", | ||
"direction": "out", | ||
"name": "res" | ||
} | ||
] | ||
} |
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,36 @@ | ||
const { SearchClient, AzureKeyCredential } = require("@azure/search-documents"); | ||
|
||
const indexName = process.env["SearchIndexName"]; | ||
const apiKey = process.env["SearchApiKey"]; | ||
const searchServiceName = process.env["SearchServiceName"]; | ||
|
||
// Create a SearchClient to send queries | ||
const client = new SearchClient( | ||
`https://` + searchServiceName + `.search.windows.net/`, | ||
indexName, | ||
new AzureKeyCredential(apiKey) | ||
); | ||
|
||
module.exports = async function (context, req) { | ||
|
||
//context.log(req); | ||
|
||
// Reading inputs from HTTP Request | ||
const q = (req.query.q || (req.body && req.body.q)); | ||
const top = (req.query.top || (req.body && req.body.top)); | ||
const suggester = (req.query.suggester || (req.body && req.body.suggester)); | ||
|
||
// Let's get the top 5 suggestions for that search term | ||
const suggestions = await client.suggest(q, suggester, {top: parseInt(top)}); | ||
//const suggestions = await client.autocomplete(q, suggester, {top: parseInt(top)}); | ||
|
||
//context.log(suggestions); | ||
|
||
context.res = { | ||
// status: 200, /* Defaults to 200 */ | ||
headers: { | ||
"Content-type": "application/json" | ||
}, | ||
body: { suggestions: suggestions.results} | ||
}; | ||
}; |
Oops, something went wrong.