使用MongoDB时,引用数据的非规范化似乎是一种非常常见的做法.然而,我没有看到使用Doctrine MongoDB ODM处理它的任何内置方法.
假设我有一个社交网络,用户可以互相关注,这里有两个示例用户:
{
_id : id1,
name: "Malcolm Reynolds",
followed: []
}
{
_id : id2,
name: "Zoe Alleyne",
followed: [
{ _id: id1, name: "Malcolm Reynolds" }
]
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我希望'name'属性被非规范化.正如我所说,Doctrine ODM似乎没有内置的方法来做到这一点.由于关于这个问题的最新一期是一年,我会尝试自己做.
虽然我在互联网上发现了很多文章,解释了非规范化在什么情况下是有用的,并提到如何保持非规范化数据的一致性,但我没有找到解释如何实现真正的数据更新过程.
在我的情况下,最终一致的数据就足够了,用户名更新和非规范化数据更新之间可能会有几个小时.我可以看到3种不同的方法:
1 - 一致性检查程序:让 后台运行的任务定期更新非规范化数据.
2 - 更新触发器: 名称字段上的每次更新都会在单次刷新中更新所有关联的非规范化数据.
3 - 混合解决方案 对于每个用户,当更新名称时,会将一个条目添加到具有更新信息的队列中(用户更新和队列中的插入将在单个刷新中进行),并且运行任务后台做了实际的更新.
第一个解决方案似乎是最容易实现的,但正如我所看到的那样,它可能非常耗费资源.第二种解决方案会使更新请求变得非常长,即使读/写比率很高,我也可能会遇到这个问题.我认为第三种解决方案是要走的路,我这样认为是对的吗?
另外,我想以干燥的方式进行,例如,我希望不必在preUpdate回调中为每个数据非规范化的Document重写相同的代码.我正在考虑制作自定义注释,这是一个好主意吗?
我有一个任意MongoDB JSON查找查询字符串,例如:
{ "address.city": "Seattle"}
Run Code Online (Sandbox Code Playgroud)
要么
{ qty: { $gt: 5, $lt: 50 }
Run Code Online (Sandbox Code Playgroud)
是否有任何现有方法从JSON字符串创建Doctrine.MongoDB.Query对象?或者直接查询mongo然后将这些结果传递给学说进行补水?
我在Symfony2中设置MongoDB时遇到问题.
眼镜:
"Symfony": "2.6.*"
"doctrine/mongodb-odm": "1.0.*@dev",
"doctrine/mongodb-odm-bundle": "3.0.*@dev"
Run Code Online (Sandbox Code Playgroud)
我在MongoDB中有2个不同的包,nxtlog和nxtsurvey使用了2个数据库.我遇到的原始问题是我没有考虑我在选项中添加的数据库名称,这导致使用数据库'default',这当然不存在.我也不想添加default_connection和default_manager,甚至也不想添加default_database,因为两个连接都用在非核心包中.
====尝试#1 ====
这是我原来的配置:
doctrine_mongodb:
connections:
nxtlog:
server: "%nxtlog_database_server%"
options:
username: "%nxtlog_database_username%"
password: "%nxtlog_database_password%"
db: "%nxtlog_database_name%"
nxtsurvey:
server: "%nxtsurvey_database_server%"
options:
username: "%nxtsurvey_database_username%"
password: "%nxtsurvey_database_password%"
db: "%nxtsurvey_database_name%"
document_managers:
nxtlog:
mappings:
NxtLogBundle: ~
nxtsurvey:
mappings:
NxtVibeSurveyBundle: ~
Run Code Online (Sandbox Code Playgroud)
为了使其工作,我在每个文档注释中添加了db的名称:
/**
* @MongoDB\Document(db="nxtlog")
*/
class ErrorLogs
Run Code Online (Sandbox Code Playgroud)
这是一个临时解决方案,但由于我的计划是在我的其他项目中重用捆绑包,我不希望必须遍历所有文档并设置数据库的名称.
====尝试#2 ====
我的第二次尝试是严格遵循文档,因此我尝试了以下方法:
doctrine_mongodb:
connections:
nxtlog_conn:
server: "%nxtlog_database_server%"
options:
username: "%nxtlog_database_username%"
password: "%nxtlog_database_password%"
connect: true
db: "%nxtlog_database_name%"
nxtsurvey_conn:
server: "%nxtsurvey_database_server%"
options:
username: "%nxtsurvey_database_username%"
password: "%nxtsurvey_database_password%"
connect: true
db: "%nxtsurvey_database_name%" …Run Code Online (Sandbox Code Playgroud) 我在使用http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html上的doctrine mongodb cookbook将mongodb与Symfony(版本2.5.0-DEV)集成时遇到了一些问题.
对于'持久对象到MongoDB'阶段,一切都还可以.当我添加" $dm->persist($script);" 行时,我的远程数据库没有任何反应,我收到错误消息:
ClassNotFoundException:尝试从/var/www/Symfony/vendor/doctrine/mongodb/lib/Doctrine/MongoDB/Connection.php第283行中的全局命名空间加载类"Mongo".您是否忘记了此类的use语句?
但是如果没有持久性行,脚本会无错误地解析(但远程数据库没有任何反应).
这是我的Symfony版本(2.5.0)特有的,是否有解决方法?我在下面粘贴了我的整个脚本,包括use语句.任何帮助,将不胜感激 :).
namespace Atlas\MpBundle\Controller;
use Atlas\MpBundle\Document\Scripts;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserjsonController extends Controller
{
public function showuserjsonAction()
{
$script = new Scripts();
$script->setName('kingstest');
$script->setDescription('just a desc test');
$script->setGroup('SMS');
$dm = $this->get('doctrine_mongodb')->getManager();
$dm->persist($script);
$dm->flush();
return new Response('Created New Document in scripts with script id '.$script->getId());
}
}
Run Code Online (Sandbox Code Playgroud) 假设这个表单利用了一个虚构的Animal文档对象类ZooCollection,它只包含symfony2中的两个属性("name"和"color").
我正在寻找一个有效的简单愚蠢的解决方案,用自动神奇的方式预先填充给定对象的表单字段(例如,用于更新?).
Acme/DemoBundle/Controller/CustomController:
public function updateAnimalAction(Request $request)
{
...
// Create the form and handle the request
$form = $this->createForm(AnimalType(), $animal);
// Set the data again << doesn't work ?
$form->setData($form->getData());
$form->handleRequest($request);
...
}
Run Code Online (Sandbox Code Playgroud) Doctrine Migrations项目是否与Doctrine MongoDB兼容?
我不清楚搜索和查看Doctrine Migrations项目是否与ODM解决方案(例如MongoDB)以及ORM解决方案兼容.
如果是,有人可以建议如何将两者结合使用的例子或文章吗?
如果不是,是否有合理的替代方案?
我简单地理解将文档的数据从一个版本的文档迁移到另一个版本的不同方法以及每个版本的优缺点.
我倾向于实现这里建议的渐进模式更改和迁移脚本的混合方法.利用Doctrine的MongoDB库中的功能,Jonathan Wage在他的帖子中写道:Doctrine MongoDB ODM Schema Migrations.
即便如此,我需要找到一些创建迁移脚本或执行数据迁移的方法,而Doctrine Migrations似乎是一个不错的首选.
另外,另一个用户警告不要使用上面提到的Jonathan Wage方法来迁移数据,而是直接针对数据库运行命令(JavaScript?).
我目前正在使用 Symfony 4 和 Doctrine MongoDB Bundle,遵循此链接中的说明: DoctrineMongoDBBundle。所以,我有一个用户文档:
src/文档/UserDocument.php
/** @MongoDB\Document(collection="user", repositoryClass="App\Repository\UserRepository") */
class UserDocument
{
/**
* @MongoDB\Id
* @var ObjectId
*/
private $id;
/**
* @MongoDB\Field(type="string", name="first_name")
* @var string
*/
private $firstName;
/**
* @MongoDB\Field(type="string", name="middle_name")
* @var string
*/
private $middleName;
/**
* @MongoDB\Field(type="string", name="last_name")
* @var string
*/
private $lastName;
}
Run Code Online (Sandbox Code Playgroud)
src/Repository/UserRepository.php
use Doctrine\ODM\MongoDB\DocumentRepository;
class UserRepository extends DocumentRepository
{
}
Run Code Online (Sandbox Code Playgroud)
src/Controller/Content.php
内容类扩展控制器
{
/**
* @Route("/content", name="content")
* @param UserRepository $user
* @return Response …Run Code Online (Sandbox Code Playgroud) 我正在使用doctrine-mongodb-odm-1.0.0-BETA10并尝试提供一些基于事件运行\InitialDocument时的自定义逻辑preUpdate。
假设\InitialDocument获得了某种状态,该状态必须表现为 new 的初始状态\StateDocument。我正在做这样的事情:
class InitDocListener implements \Doctrine\Common\EventSubscriber {
public function getSubscribedEvents()
{
return [
Events::preUpdate
];
}
public function preUpdate($args){
$document = $args->getDocument();
if($document instanceOf InitialDocument && $document->getState() == 'mine'){
$stateDocument = new \StateDocument();
$stateDocument->setInitDocument($document);
$args->getDocumentManager()->persist($stateDocument);
//no flush cause recursion happens
}
}
}
Run Code Online (Sandbox Code Playgroud)
prePersist事件\StateDocument发生,但它不会将新文档保留在数据库中。因此postPersist事件永远不会被触发。
还有一些更多的自定义逻辑,但都在事件范围内。在某些时候,该逻辑可能会抛出异常,该异常必须停止更新事件,InitialDocument因此InitialDocument状态取决于\StateDocument业务范围的创建过程。
我怎么解决这个问题?preFlush在changeSet重新计算之前运行的事件不确定InitialDocument实例。所以这是一种“搜索”更新的技巧preFlush,让我认为这不是正确的方法。请给我一个合适的建议。谢谢。
我有用户和帖子的集合.
用户看起来像
{ "_id" : ObjectId("5089cc4c7b03b9902b000000"), "facebook_id" : "522128874" }
Run Code Online (Sandbox Code Playgroud)
帖子看起来像
{ "_id" : ObjectId("508aa21b7b03b9780800000f"), "facebook_id" : "10150709375878875", "user" : DBRef("User", ObjectId("5089cc4c7b03b9902b000000")), "message" : " Julia dream, dreamboat queen, queen of all my dreams", "updated_time" : 1333502938 }
Run Code Online (Sandbox Code Playgroud)
我想查找特定用户的所有帖子.
$user = $userRepo->findOneByFacebookId('522128874');
$posts = $postRepo->findOneByUser($user)
Run Code Online (Sandbox Code Playgroud)
它不起作用.我也试过了
$posts = $postRepo->findOneBy(array('user' => $user))
Run Code Online (Sandbox Code Playgroud)
和
$posts = $postRepo->findOneBy(array('user' => $user->getId()))
Run Code Online (Sandbox Code Playgroud) mongodb ×7
symfony ×7
php ×5
doctrine-odm ×3
doctrine-orm ×2
controller ×1
doctrine ×1
forms ×1
odm ×1
persistence ×1
symfony-2.1 ×1