You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整JHipster生成的查询逻辑,实现storeName或identifier的OR条件模糊查询?

How to Implement OR Logic Instead of AND in JHipster's Query Parameters

The Problem

Right now, your code is fetching cash registers where both storeName and identifier contain your search term event.query. You need to adjust this to return results where either field matches the term. Here's your current frontend query code:

this.cashRegisterService
    .query({
        'storeName.contains': event.query,
        'identifier.contains': event.query,
    })
    .subscribe(data => {
        this.cashregisters = (data.body || []).map(cashRegister => ({
            id: cashRegister.id,
            name: `${cashRegister.identifier} ${cashRegister.storeName} (${cashRegister.mallName})`,
        }));
    });

And here's the JHipster-generated service and request option helper code you're using:

// CashRegisterService's query method
query(req?: any): Observable<EntityArrayResponseType> {
    const options = createRequestOption(req);
    return this.http.get<ICashRegister[]>(this.resourceUrl, { params: options, observe: 'response' });
}

// createRequestOption function
export const createRequestOption = (req?: any): HttpParams => {
    let options: HttpParams = new HttpParams();
    if (req) {
        Object.keys(req).forEach(key => {
            if (key !== 'sort') {
                options = options.set(key, req[key]);
            }
        });
        if (req.sort) {
            req.sort.forEach((val: string) => {
                options = options.append('sort', val);
            });
        }
    }
    return options;
};

The Solution

JHipster's backend relies on Spring Data REST, which supports OR logic via the or query parameter. We need to tweak both your frontend query structure and the createRequestOption function to handle this correctly (the original function uses set() which overwrites duplicate keys, but OR requires repeating the or parameter for each condition).

Step 1: Update the Frontend Query

Replace your current query object with an or array containing each of your match conditions. This tells the backend to treat these criteria as OR'd:

this.cashRegisterService
    .query({
        or: [
            { 'storeName.contains': event.query },
            { 'identifier.contains': event.query }
        ]
    })
    .subscribe(data => {
        this.cashregisters = (data.body || []).map(cashRegister => ({
            id: cashRegister.id,
            name: `${cashRegister.identifier} ${cashRegister.storeName} (${cashRegister.mallName})`,
        }));
    });

Step 2: Modify the createRequestOption Function

The original helper doesn't process the or array properly. We need to loop through the array, convert each condition to the format Spring Data REST expects (property.queryMethod:value), and append each as a separate or parameter:

export const createRequestOption = (req?: any): HttpParams => {
    let options: HttpParams = new HttpParams();
    if (req) {
        Object.keys(req).forEach(key => {
            if (key !== 'sort') {
                // Handle OR conditions specially
                if (key === 'or' && Array.isArray(req[key])) {
                    req[key].forEach((condition: any) => {
                        const [conditionKey] = Object.keys(condition);
                        const conditionValue = condition[conditionKey];
                        // Format as "property.queryMethod:value" and append to params
                        options = options.append('or', `${conditionKey}:${conditionValue}`);
                    });
                } else {
                    options = options.set(key, req[key]);
                }
            }
        });
        if (req.sort) {
            req.sort.forEach((val: string) => {
                options = options.append('sort', val);
            });
        }
    }
    return options;
};

Why This Works

Spring Data REST interprets multiple or parameters as OR'd conditions. Your final request URL will look like this:
?or=storeName.contains:yourSearchTerm&or=identifier.contains:yourSearchTerm

The backend automatically translates this into SQL logic:
WHERE storeName LIKE '%yourSearchTerm%' OR identifier LIKE '%yourSearchTerm%'

Alternative (No Global Function Modification)

If you don't want to change the global createRequestOption function, you can construct the HttpParams directly in your component:

const searchParams = new HttpParams()
    .append('or', `storeName.contains:${event.query}`)
    .append('or', `identifier.contains:${event.query}`);

// Call the HTTP client directly instead of using the service's query method
this.http.get<ICashRegister[]>(this.cashRegisterService.resourceUrl, { params: searchParams, observe: 'response' })
    .subscribe(data => {
        this.cashregisters = (data.body || []).map(cashRegister => ({
            id: cashRegister.id,
            name: `${cashRegister.identifier} ${cashRegister.storeName} (${cashRegister.mallName})`,
        }));
    });

This approach is less reusable but avoids altering the global request helper.


内容的提问来源于stack exchange,提问作者Mihnea Burluc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:34:09