Fixed minor bugs and improved fluent api
This commit is contained in:
@ -29,6 +29,16 @@ import A from './aggregation'
|
||||
import * as t from './types'
|
||||
import T from '../es-types'
|
||||
|
||||
type SearchRequest = Required<T.SearchRequest>['body']
|
||||
interface BoolQuery {
|
||||
filter?: T.QueryContainer[]
|
||||
minimum_should_match?: T.MinimumShouldMatch
|
||||
must?: T.QueryContainer[]
|
||||
must_not?: T.QueryContainer[]
|
||||
should?: T.QueryContainer[]
|
||||
_name?: string
|
||||
}
|
||||
|
||||
const kState = Symbol('dsl-query-state')
|
||||
type MultiType = string | number | boolean
|
||||
|
||||
@ -36,15 +46,20 @@ type MultiType = string | number | boolean
|
||||
// and automatically call `query.build()`
|
||||
|
||||
class FluentQ {
|
||||
[kState]: Record<string, any>[]
|
||||
[kState]: (SearchRequest | T.QueryContainer | T.QueryContainer[] | BoolQuery)[]
|
||||
constructor () {
|
||||
this[kState] = []
|
||||
}
|
||||
|
||||
build (): Record<string, any> {
|
||||
build (): SearchRequest {
|
||||
return Q(...this[kState])
|
||||
}
|
||||
|
||||
buildQuery (): T.QueryContainer {
|
||||
const b = Q(...this[kState])
|
||||
return b.query != null ? b.query : {}
|
||||
}
|
||||
|
||||
param (key: string): Symbol {
|
||||
return Q.param(key)
|
||||
}
|
||||
@ -123,14 +138,16 @@ class FluentQ {
|
||||
term (key: string, val: (MultiType | Symbol)[]): this
|
||||
term (key: string, val: (MultiType | Symbol)[], opts: T.TermsQuery): this
|
||||
term (key: string, val: any, opts?: any): this {
|
||||
if (Array.isArray(val)) {
|
||||
return this.terms(key, val, opts)
|
||||
if (Array.isArray(val) && opts == null) {
|
||||
return this.terms(key, val)
|
||||
}
|
||||
this[kState].push(Q.term(key, val, opts))
|
||||
return this
|
||||
}
|
||||
|
||||
terms (key: string, val: (MultiType | Symbol)[], opts?: T.TermsQuery): this {
|
||||
terms (key: string, val: (MultiType | Symbol)[]): this
|
||||
terms (key: string, val: (MultiType | Symbol)[], opts: T.TermsQuery): this
|
||||
terms (key: string, val: (MultiType | Symbol)[], opts?: any): this {
|
||||
this[kState].push(Q.terms(key, val, opts))
|
||||
return this
|
||||
}
|
||||
@ -200,42 +217,49 @@ class FluentQ {
|
||||
}
|
||||
|
||||
must (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.must(...queries.map(q => q.build())))
|
||||
// @ts-expect-error
|
||||
this[kState].push(Q.must(...queries.flatMap(q => q[kState])))
|
||||
return this
|
||||
}
|
||||
|
||||
should (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.should(...queries.map(q => q.build())))
|
||||
// @ts-expect-error
|
||||
this[kState].push(Q.should(...queries.flatMap(q => q[kState])))
|
||||
return this
|
||||
}
|
||||
|
||||
mustNot (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.mustNot(...queries.map(q => q.build())))
|
||||
// @ts-expect-error
|
||||
this[kState].push(Q.mustNot(...queries.flatMap(q => q[kState])))
|
||||
return this
|
||||
}
|
||||
|
||||
filter (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.filter(...queries.map(q => q.build())))
|
||||
// @ts-expect-error
|
||||
this[kState].push(Q.filter(...queries.flatMap(q => q[kState])))
|
||||
return this
|
||||
}
|
||||
|
||||
bool (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.bool(...queries.map(q => q.build())))
|
||||
// @ts-expect-error
|
||||
this[kState].push(Q.bool(...queries.flatMap(q => q[kState])))
|
||||
return this
|
||||
}
|
||||
|
||||
and (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.and(...queries.map(q => q.build())))
|
||||
and (...blocks: FluentQ[]): this {
|
||||
const { query = {}, ...searchRequest } = this.build()
|
||||
this[kState] = [searchRequest, Q.and(query, ...blocks.map(q => q.buildQuery()))]
|
||||
return this
|
||||
}
|
||||
|
||||
or (...queries: FluentQ[]): this {
|
||||
this[kState].push(Q.or(...queries.map(q => q.build())))
|
||||
or (...blocks: FluentQ[]): this {
|
||||
const { query = {}, ...searchRequest } = this.build()
|
||||
this[kState] = [searchRequest, Q.and(query, ...blocks.map(q => q.buildQuery()))]
|
||||
return this
|
||||
}
|
||||
|
||||
not (query: FluentQ): this {
|
||||
this[kState].push(Q.not(query.build()))
|
||||
this[kState].push(Q.not(query.buildQuery()))
|
||||
return this
|
||||
}
|
||||
|
||||
@ -296,6 +320,16 @@ class FluentQ {
|
||||
this[kState].push(obj)
|
||||
return this
|
||||
}
|
||||
|
||||
clone (): FluentQ {
|
||||
const F = new FluentQ()
|
||||
F[kState] = this[kState].slice()
|
||||
return F
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return this.build()
|
||||
}
|
||||
}
|
||||
|
||||
export default function build () {
|
||||
|
||||
@ -40,7 +40,7 @@ type QueryBlock = { query: T.QueryContainer }
|
||||
type MultiType = string | number | boolean
|
||||
|
||||
function Q (...blocks: (SearchRequest | T.QueryContainer | T.QueryContainer[] | BoolQuery)[]): SearchRequest {
|
||||
blocks = blocks.flat() as (SearchRequest | T.QueryContainer | BoolQuery)[]
|
||||
blocks = blocks.flat()
|
||||
const topLevelKeys = [
|
||||
'aggs',
|
||||
'collapse',
|
||||
@ -300,22 +300,24 @@ namespace Q {
|
||||
|
||||
export function term (key: string, val: MultiType | Symbol): { term: Record<string, MultiType> }
|
||||
export function term (key: string, val: MultiType | Symbol, opts: T.TermQuery): { term: Record<string, T.TermQuery> }
|
||||
export function term (key: string, val: (MultiType | Symbol)[]): { terms: T.TermsQuery }
|
||||
export function term (key: string, val: (MultiType | Symbol)[], opts: T.TermsQuery): { terms: T.TermsQuery }
|
||||
export function term (key: string, val: (MultiType | Symbol)[]): { terms: Record<string, string[]> }
|
||||
export function term (key: string, val: (MultiType | Symbol)[], opts: T.TermsQuery): { term: Record<string, T.TermQuery> }[]
|
||||
export function term (key: string, val: any, opts?: any): any {
|
||||
if (Array.isArray(val)) {
|
||||
return Q.terms(key, val, opts)
|
||||
if (Array.isArray(val) && opts == null) {
|
||||
return Q.terms(key, val)
|
||||
}
|
||||
return generateValueObject('term', key, val, opts)
|
||||
}
|
||||
|
||||
export function terms (key: string, val: (MultiType | Symbol)[], opts?: T.TermsQuery): { terms: T.TermsQuery } {
|
||||
return {
|
||||
terms: {
|
||||
[key]: val,
|
||||
...opts
|
||||
export function terms (key: string, val: (MultiType | Symbol)[]): { terms: Record<string, string[]> }
|
||||
export function terms (key: string, val: (MultiType | Symbol)[], opts: T.TermsQuery): { terms: Record<string, T.TermsQuery> }
|
||||
export function terms (key: string, val: (MultiType | Symbol)[], opts?: any): any {
|
||||
if (opts == null) {
|
||||
return {
|
||||
terms: { [key]: val }
|
||||
}
|
||||
}
|
||||
return { terms: opts }
|
||||
}
|
||||
|
||||
export function termsSet (key: string, val: (string | Symbol)[], opts?: T.TermsSetQuery): { terms_set: Record<string, T.TermsSetQuery> } {
|
||||
|
||||
Reference in New Issue
Block a user