feat: added nested op
This commit is contained in:
parent
e655b9b325
commit
ce22f77b32
2 changed files with 43 additions and 21 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
import { Body, Controller, Post, Route, Security, SuccessResponse, Tags } from "tsoa";
|
import { Body, Controller, Post, Route, Security, SuccessResponse, Tags } from "tsoa";
|
||||||
import HttpStatusCode from "../interfaces/http-status";
|
import HttpStatusCode from "../interfaces/http-status";
|
||||||
import esClient from "../elasticsearch";
|
import esClient from "../elasticsearch";
|
||||||
import { Search } from "../interfaces/search";
|
import { Search, SearchInfo, SearchOperator } from "../interfaces/search";
|
||||||
import { StorageFile } from "../interfaces/storage-fs";
|
import { StorageFile } from "../interfaces/storage-fs";
|
||||||
|
import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types";
|
||||||
|
|
||||||
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
|
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
|
||||||
|
|
||||||
|
|
@ -17,19 +18,23 @@ export class SearchController extends Controller {
|
||||||
public async searchFile(@Body() search: Search): Promise<StorageFile[]> {
|
public async searchFile(@Body() search: Search): Promise<StorageFile[]> {
|
||||||
const type = ["match", "match_phrase"] as const;
|
const type = ["match", "match_phrase"] as const;
|
||||||
|
|
||||||
|
const searchMapCallback = (v: SearchInfo | SearchOperator): QueryDslQueryContainer => {
|
||||||
|
if ("field" in v && "value" in v) {
|
||||||
|
return { [type[search.exact || v.exact ? 1 : 0]]: { [v.field]: v.value } };
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
bool: { must: v.AND?.map(searchMapCallback), should: v.OR?.map(searchMapCallback) },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const result = await esClient.search<StorageFile & { attachment: Record<string, string> }>({
|
const result = await esClient.search<StorageFile & { attachment: Record<string, string> }>({
|
||||||
index: DEFAULT_INDEX,
|
index: DEFAULT_INDEX,
|
||||||
query: {
|
query: {
|
||||||
bool: {
|
bool: {
|
||||||
must: search.AND?.map((v) => ({
|
must: search.AND?.map(searchMapCallback),
|
||||||
[type[search.exact || v.exact ? 1 : 0]]: { [v.field]: v.value },
|
should: search.OR?.map(searchMapCallback),
|
||||||
})),
|
must_not: { match: { hidden: true } },
|
||||||
should: search.OR?.map((v) => ({
|
|
||||||
[type[search.exact || v.exact ? 1 : 0]]: { [v.field]: v.value },
|
|
||||||
})),
|
|
||||||
must_not: {
|
|
||||||
match: { hidden: true },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
post_filter: {
|
post_filter: {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,32 @@
|
||||||
export interface Search {
|
import { QueryDslQueryContainer } from "@elastic/elasticsearch/lib/api/types";
|
||||||
AND?: {
|
|
||||||
field: string;
|
export interface SearchInfo {
|
||||||
value: string;
|
field: string;
|
||||||
exact?: boolean;
|
value: string;
|
||||||
}[];
|
|
||||||
OR?: {
|
|
||||||
field: string;
|
|
||||||
value: string;
|
|
||||||
exact?: boolean;
|
|
||||||
}[];
|
|
||||||
exact?: boolean;
|
exact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SearchOperator {
|
||||||
|
AND?: (SearchInfo | SearchOperator)[];
|
||||||
|
OR?: (SearchInfo | SearchOperator)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Search extends SearchOperator {
|
||||||
recursive?: boolean;
|
recursive?: boolean;
|
||||||
path?: string[];
|
path?: string[];
|
||||||
|
exact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapCallback(exact: boolean) {
|
||||||
|
const type = ["match", "match_phrase"] as const;
|
||||||
|
return (v: SearchInfo | SearchOperator): QueryDslQueryContainer => {
|
||||||
|
return "field" in v && "value" in v
|
||||||
|
? { [type[exact || v.exact ? 1 : 0]]: { [v.field]: v.value } }
|
||||||
|
: {
|
||||||
|
bool: {
|
||||||
|
must: v.AND?.map(mapCallback(exact)),
|
||||||
|
should: v.OR?.map(mapCallback(exact)),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue