Laravel复杂查询

时间:2016-09-29 18:31:08

标签: mysql eloquent laravel-5.1

我正在重新编写已编码的"制作"系统基于一组数据库"食谱"最多包含五个项目和数量(例如:item1item1qty)。现在,以前以正确的顺序对配方中的项目进行排序非常重要,这使得验证变得简单,因为它只是查看用户放置的内容item1item1qty等并直接匹配它们。

我们现在希望它能以任何顺序接受成分。我知道这可以通过查询功能来完成,但是我担心我的基础因为我提出的解决方案将其标记为有效的配方,如果用户甚至有一部分配方(比如配方包含3种成分,如果他们只输入其中一种成分,即使没有其他2种适当的成分和量,也会验证。我的解决方案也很长,有没有办法简化它?

$recipe = DataRecipe::where(function ($query) use($request) {
        $query->where(function ($q) use($request) {
            $q->where(function($q2) use ($request) {
                $q2->where('item1', $request->item1)->where('item1qty', $request->item1qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item2', $request->item1)->where('item2qty', $request->item1qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item3', $request->item1)->where('item3qty', $request->item1qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item4', $request->item1)->where('item4qty', $request->item1qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item5', $request->item1)->where('item5qty', $request->item1qty);
            });
        })->where(function ($q) use($request) {
            $q->where(function($q2) use ($request) {
                $q2->where('item1', $request->item2)->where('item1qty', $request->item2qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item2', $request->item2)->where('item2qty', $request->item2qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item3', $request->item2)->where('item3qty', $request->item2qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item4', $request->item2)->where('item4qty', $request->item2qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item5', $request->item2)->where('item5qty', $request->item2qty);
            });
        })->where(function ($q) use($request) {
            $q->where(function($q2) use ($request) {
                $q2->where('item1', $request->item3)->where('item1qty', $request->item3qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item2', $request->item3)->where('item2qty', $request->item3qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item3', $request->item3)->where('item3qty', $request->item3qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item4', $request->item3)->where('item4qty', $request->item3qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item5', $request->item3)->where('item5qty', $request->item3qty);
            });
        })->where(function ($q) use($request) {
            $q->where(function($q2) use ($request) {
                $q2->where('item1', $request->item4)->where('item1qty', $request->item4qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item2', $request->item4)->where('item2qty', $request->item4qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item3', $request->item4)->where('item3qty', $request->item4qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item4', $request->item4)->where('item4qty', $request->item4qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item5', $request->item4)->where('item5qty', $request->item4qty);
            });
        })->where(function ($q) use($request) {
            $q->where(function($q2) use ($request) {
                $q2->where('item1', $request->item5)->where('item1qty', $request->item5qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item2', $request->item5)->where('item2qty', $request->item5qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item3', $request->item5)->where('item3qty', $request->item5qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item4', $request->item5)->where('item4qty', $request->item5qty);
            })->orWhere(function($q2) use ($request) {
                $q2->where('item5', $request->item5)->where('item5qty', $request->item5qty);
            });
        });
    })->where('tool', $request->tool)->first();

1 个答案:

答案 0 :(得分:0)

有可能更好的方法来做到这一点,但只要使代码更具可读性,你就可以使用循环:

$recipe = DataRecipe::where(function ($query) use ($request) {

    foreach (range(1, 5) as $i) {

        $item = $request->{'item' . $i};
        $quantity = $request->{'item' . $i . 'qty'};

        $query->where(function ($q) use ($item, $quantity) {

            $q->where(function ($q2) use ($item, $quantity) {
                $q2->where('item1', $item)->where('item1qty', $quantity);
            })->orWhere(function ($q2) use ($item, $quantity) {
                $q2->where('item2', $item)->where('item2qty', $quantity);
            })->orWhere(function ($q2) use ($item, $quantity) {
                $q2->where('item3', $item)->where('item3qty', $quantity);
            })->orWhere(function ($q2) use ($item, $quantity) {
                $q2->where('item4', $item)->where('item4qty', $quantity);
            })->orWhere(function ($q2) use ($item, $quantity) {
                $q2->where('item5', $item)->where('item5qty', $quantity);
            });
        });
    }

})->where('tool', $request->tool)->first();

如果您的应用程序可以实现,我可能会考虑重构您的代码和数据库,这样您就可以在DataRecipe和项目之间建立标准的一对二关系。这样您就不必担心item1item2等等。如果您只能拥有一定数量的项目,那么您可以使用验证来确保您永远不会许多。

希望这有帮助!