我正在尝试在Web API上减少数据库查询次数,但遇到了困难。
我的数据库有3个集合:playground
,widget
和token
。
一个游乐场(playground)有多个小部件(widgets),一个小部件有一个令牌(token)。
每个关系使用referencesOne
/ referenceMany
。
以下是我简化后的模型:
/**
* @MongoDB\Document()
*/
class Widget
{
/**
* @MongoDB\ReferenceOne(targetDocument="Token", inversedBy="widgets")
*/
protected $token;
/**
* @MongoDB\ReferenceOne(targetDocument="Playground", inversedBy="widgets")
*/
protected $playground;
}
/**
* @MongoDB\Document()
*/
class Playground
{
/**
* @MongoDB\ReferenceMany(targetDocument="Widget", mappedBy="playground")
*/
protected $widgets;
}
/**
* @MongoDB\Document()
*/
class Token
{
/**
* @MongoDB\ReferenceMany(targetDocument="Widget", mappedBy="token")
*/
protected $widgets;
}
我需要使用完整的 playground,包括所有的 widgets 和 tokens,但默认情况下,Doctrine 执行了太多的查询:一个用于获取 playground(好的),一个用于获取所有映射的 widgets(好的),而对于每个 widget,都会执行一次查询以获取 token(不好)。是否有一种方式可以一次性查询所有的 tokens 而不是逐个获取?
我已经查看了 prime,但它似乎不能解决我的问题...
除了使用查询构建器并手动转换所有对象以减少查询计数之外,是否还有其他方法?
编辑: 正如我在评论中所添加的,我所要寻找的是将 playground 及其所有依赖项作为一个大对象获取,对其进行 json 编码,并将其返回到响应中。
目前的做法是查询 playground 并编码它,但是 Doctrine 以非高效的方式填充了这些依赖项:首先是查询获取 playgroung,然后,有另一个查询来获取相关的 widgets,对于每个 widget 都会有一个查询以获取其 token。
由于一个 playground 可能有数百个 widgets,因此会导致数百个数据库查询。
我所要寻找的是一种告诉 Doctrine 仅使用 3 个查询(一个用于获取 playgroung,一个用于获取 widgets,一个用于获取 tokens)获取所有这些数据的方法。
$tokenRepository->findAll();
来获取所有的“Token”,或者使用$tokenRepository->findBy(array $criteria);
,其中$criteria
是你的查询参数。 - EtshyfindBy(['widgets.id' => $widgetsIds])
,其中$widgetsIds
是一个 ID 数组。但我真的不确定findBy
能否使用这样的数组。 - Etshy$lookup
(请参见此处https://medium.com/@alcaeus/introducing-doctrine-mongodb-odm-1-2-bd85d6c8261a),除非有一种方法将所有现有文档迁移到新的ref格式? - ᴄʀᴏᴢᴇᴛ