2016-05-05 00:34:54 +08:00
|
|
|
import {AutoCompleteItem, AutoCompeleteTypes} from "../../../common/entities/AutoCompleteItem";
|
|
|
|
import {ISearchManager} from "../ISearchManager";
|
|
|
|
import {DirectoryModel} from "./entities/DirectoryModel";
|
|
|
|
import {PhotoModel} from "./entities/PhotoModel";
|
2016-05-10 03:43:52 +08:00
|
|
|
import {SearchResult} from "../../../common/entities/SearchResult";
|
2016-05-05 00:34:54 +08:00
|
|
|
|
2016-05-09 23:04:56 +08:00
|
|
|
export class MongoSearchManager implements ISearchManager {
|
2016-05-05 00:34:54 +08:00
|
|
|
|
2016-05-09 23:04:56 +08:00
|
|
|
constructor() {
|
2016-05-05 00:34:54 +08:00
|
|
|
}
|
|
|
|
|
2016-05-09 23:04:56 +08:00
|
|
|
autocomplete(text, cb:(error:any, result:Array<AutoCompleteItem>) => void) {
|
2016-05-05 00:34:54 +08:00
|
|
|
|
|
|
|
console.log("autocomplete: " + text);
|
|
|
|
let items:Array<AutoCompleteItem> = [];
|
2016-05-16 01:36:23 +08:00
|
|
|
let promises = [];
|
|
|
|
|
|
|
|
promises.push(
|
|
|
|
PhotoModel.find({name: {$regex: text, $options: "i"}})
|
|
|
|
.limit(10).select('name').exec().then((res:Array<any>)=> {
|
|
|
|
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.image));
|
|
|
|
}));
|
|
|
|
|
|
|
|
promises.push(
|
|
|
|
PhotoModel.find({"metadata.positionData.city": {$regex: text, $options: "i"}})
|
|
|
|
.limit(10).select('metadata.positionData.city').exec().then((res:Array<any>)=> {
|
|
|
|
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.city), AutoCompeleteTypes.position));
|
|
|
|
}));
|
|
|
|
|
|
|
|
promises.push(
|
|
|
|
PhotoModel.find({"metadata.positionData.state": {$regex: text, $options: "i"}})
|
|
|
|
.limit(10).select('metadata.positionData.state').exec().then((res:Array<any>)=> {
|
|
|
|
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.state), AutoCompeleteTypes.position));
|
|
|
|
}));
|
|
|
|
|
|
|
|
promises.push(
|
|
|
|
PhotoModel.find({"metadata.positionData.country": {$regex: text, $options: "i"}})
|
|
|
|
.limit(10).select('metadata.positionData.country').exec().then((res:Array<any>)=> {
|
|
|
|
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.metadata.positionData.country), AutoCompeleteTypes.position));
|
|
|
|
}));
|
|
|
|
|
|
|
|
//TODO: fix caseinsensitivity
|
|
|
|
promises.push(
|
|
|
|
PhotoModel.find({"metadata.keywords": {$regex: text, $options: "i"}})
|
|
|
|
.limit(10).select('metadata.keywords').exec().then((res:Array<any>)=> {
|
|
|
|
res.forEach((photo)=> {
|
|
|
|
items = items.concat(this.encapsulateAutoComplete(photo.metadata.keywords.filter(k => k.indexOf(text) != -1), AutoCompeleteTypes.keyword));
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
|
|
|
|
promises.push(
|
2016-05-09 23:04:56 +08:00
|
|
|
DirectoryModel.find({
|
2016-05-16 01:36:23 +08:00
|
|
|
name: {$regex: text, $options: "i"}
|
|
|
|
}).limit(10).select('name').exec().then((res:Array<any>)=> {
|
2016-05-09 23:04:56 +08:00
|
|
|
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.directory));
|
2016-05-16 01:36:23 +08:00
|
|
|
}));
|
2016-05-05 00:34:54 +08:00
|
|
|
|
|
|
|
|
2016-05-16 01:36:23 +08:00
|
|
|
Promise.all(promises).then(()=> {
|
|
|
|
return cb(null, this.autoCompleteItemsUnique(items));
|
|
|
|
}).catch((err)=> {
|
|
|
|
console.error(err);
|
|
|
|
return cb(err, null);
|
2016-05-05 00:34:54 +08:00
|
|
|
});
|
2016-05-16 01:36:23 +08:00
|
|
|
|
|
|
|
|
2016-05-05 00:34:54 +08:00
|
|
|
}
|
|
|
|
|
2016-05-10 03:43:52 +08:00
|
|
|
search(text, cb:(error:any, result:SearchResult) => void) {
|
|
|
|
console.log("instantSearch: " + text);
|
|
|
|
let result:SearchResult = new SearchResult();
|
|
|
|
result.searchText = text;
|
|
|
|
PhotoModel.find({
|
|
|
|
name: {
|
|
|
|
$regex: text,
|
|
|
|
$options: "i"
|
|
|
|
}
|
|
|
|
}).populate('directory', 'name path').exec((err, res:Array<any>) => {
|
|
|
|
if (err || !res) {
|
|
|
|
return cb(err, null);
|
|
|
|
}
|
|
|
|
result.photos = res;
|
|
|
|
|
|
|
|
DirectoryModel.find({
|
|
|
|
name: {
|
|
|
|
$regex: text,
|
|
|
|
$options: "i"
|
|
|
|
}
|
|
|
|
}).select('name').exec((err, res:Array<any>) => {
|
|
|
|
if (err || !res) {
|
|
|
|
return cb(err, null);
|
|
|
|
}
|
|
|
|
result.directories = res;
|
|
|
|
return cb(null, result);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
instantSearch(text, cb:(error:any, result:SearchResult) => void) {
|
|
|
|
console.log("instantSearch: " + text);
|
|
|
|
let result:SearchResult = new SearchResult();
|
|
|
|
result.searchText = text;
|
|
|
|
PhotoModel.find({
|
|
|
|
name: {
|
|
|
|
$regex: text,
|
|
|
|
$options: "i"
|
|
|
|
}
|
|
|
|
}).limit(10).populate('directory', 'name path').exec((err, res:Array<any>) => {
|
|
|
|
if (err || !res) {
|
|
|
|
return cb(err, null);
|
|
|
|
}
|
|
|
|
result.photos = res;
|
|
|
|
|
|
|
|
DirectoryModel.find({
|
|
|
|
name: {
|
|
|
|
$regex: text,
|
|
|
|
$options: "i"
|
|
|
|
}
|
|
|
|
}).limit(10).exec((err, res:Array<any>) => {
|
|
|
|
if (err || !res) {
|
|
|
|
return cb(err, null);
|
|
|
|
}
|
|
|
|
result.directories = res;
|
|
|
|
return cb(null, result);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-05-09 23:04:56 +08:00
|
|
|
private encapsulateAutoComplete(values:Array<string>, type:AutoCompeleteTypes) {
|
2016-05-05 00:34:54 +08:00
|
|
|
let res = [];
|
2016-05-09 23:04:56 +08:00
|
|
|
values.forEach((value)=> {
|
|
|
|
res.push(new AutoCompleteItem(value, type));
|
2016-05-05 00:34:54 +08:00
|
|
|
});
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2016-05-16 01:36:23 +08:00
|
|
|
private autoCompleteItemsUnique(array:Array<AutoCompleteItem>) {
|
|
|
|
var a = array.concat();
|
|
|
|
for (var i = 0; i < a.length; ++i) {
|
|
|
|
for (var j = i + 1; j < a.length; ++j) {
|
|
|
|
if (a[i].equals(a[j]))
|
|
|
|
a.splice(j--, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2016-05-05 00:34:54 +08:00
|
|
|
|
|
|
|
}
|