How do you update a mongodb document while replacing the entire document? - php

If I have a document with two values:
{
"name" : "Bob",
"location" "France"
}
And then pass an array to the document that contains "name", "country". How do I ensure that the entire document is updated, with "location" removed?
I will not be aware of the differences between the two documents, so I wont be able to unset a specific field. I am looking for a method to simply replace the document data with the array supplied.

If you supply update with a new document containing the records you want, you will replace the document.
For example:
db.so.insert({"name":"Bob", "location": "France"})
db.so.update({"name":"Bob", "location": "France"}, {"name":"Roberto", "country":"Italy"})
db.so.find()
{ "_id" : ObjectId(), "name" : "Roberto", "country" : "Italy" }
Of course, if you had the _id of the document, this would be a better way of specifying the update (rather than passing back the document you just inserted like above)

Related

DocuSign API Replace template document but keep fields

I want to use the existing fields from a server template over another document.
At first I tried attaching the document at the same level as inline/server.
If I have the signer defined it gives me a 400 error, if I leave it off (did by accident) it completely wipes out the fields and shows the attached document.
Second I tried attaching the document to the inline template but that results in the attached document not appearing, it just operates like normal.
update
After adding additional debugging and research I now know that attaching it to the inline template was incorrect. After adding debug to read the 400 response I am getting this error:
"The DocumentId specified in the tab element does not refer to a document in this envelope. Tab refers to DocumentId 32475214 which is not present."
DocumentId is being set to 1 which is apparently wrong.
Which led me to this question on SO. In which a comment mentions that the ID kicked back from the 400 should be used.
After I hard coded this ID I see the replacement operation is a success!
However I now need to find a way find and to plug that value in programatically.
Detail
I am using the DocuSign php sdk to help me build the data structure and access the api.
Use the listTemplateDocuments API to retrieve the documentId for the template.
The documentId retrieved in the above step should be used in the CompositeTemplate of CreateEnvelope request
{
"emailSubject": "Tabs should remain from the Server Template",
"status": "sent",
"compositeTemplates": [
{
"document": {
"documentId": "<document Id>", //Use the documentId retrieved using the listTemplateDocuments api
"name": "Replaced Document",
"fileExtension": "txt",
"documentBase64": "RG9jIFRXTyBUV08gVFdP"
},
"serverTemplates": [
{
"sequence": "1",
"templateId": "<Server Template Id Here>"
}
]
}
]
}

How can I create unique IDs for embedded documents in MongoDB using PHP?

I have a collection of posts
{
"uid": ObjectId("57e58f6a1ccbdd1407000029"),
"text": "Post content goes here!",
"comments": [
{
"_id": // unique ID
"comment": "Comment 1",
},
{
"_id": // unique ID
"comment": "Comment 2",
}
]
}
The above is a simple example of the post collection's document structure.
I was thinking that, what would be the best way to generate and store a unique id (using PHP) for each comment so that it could be selected specifically to edit or delete.
I agree with Markus' comment, but to answer the question you should consider
generating BSON ObjectId which is pretty much unique and doesn't require anything additional
generating UUID using for instance ramsey/uuid

How to get form fields in Facebook Lead Ads API?

I'm using Facebook Lead Ads API. I need to retrieve all fields from a form by ID. I know I can:
get all forms by calling /<PAGE_ID>/leadgen_forms, but it doesn't return the fields
get a form by /<FORM_ID>, but it displays only the name and a few
data, but not fields
get all leads by /<FORM_ID>/leads - it gives me the fields in each
lead, but only if I have leads; there's also another problem with this solution - the order of the fields is random
Is there any dedicated way to retrieve leadgen form fields, even when there are no leads yet?
I found out that I can download the CSV and in the first row, it gives me all fields IDs (and some other columns). I'm not sure though how I can read the content of this file in PHP, because it gives me some HTML when I try to use get_file_contents() on it.
You can get these by adding non-default field questions, so the url becomes /<form_id>?fields=id,name,questions.
The official docs don't describe the fields available for reading but the questions field and its nested fields are described in the params used for creating a lead form.
Example output
{
"id": "1234567890000",
"name": "test form",
"questions": [
{
"key": "name",
"label": "Full Name",
"type": "FULL_NAME",
"id": "777888999000111"
},
{
"key": "email",
"label": "Email Address",
"type": "EMAIL",
"id": "111222333444555"
}
]
}
Just a warning since this answer comes first on google search.
Since Facebook API v5.0 field "qualifiers" is removed and will throw an error.
Replace it with "questions" which is similar (if not exact) syntax as qualifiers. Found out the hard way on production server...

php mongodb count nested attributes

I have the following document structure:
"messages": {
"_id" : ObjectId("515a4de9c1a3c09c19000001"),
"author" : "50fd0d38c1a3c04c27000000",recipient" : "5159a292c1a3c01d5b000005",
"conversation" : [
{
"author" : "50fd0d38c1a3c04c27000000",
"date" : ISODate("2013-04-02T03:18:01.204Z"),
"message" : "hello test",
"read" : false
},
{
"message" : "reply test",
"date" : ISODate("2013-04-02T03:36:57.444Z"),
"author" : "5159a292c1a3c01d5b000005",
"read" : true
}....
Is it possible to get the total number of conversation messages where conversation.read is false and the author (conversation.author) of the unread message is not the person who started the conversation?
I'm currently finding documents that have conversations.read as false and then looping through them in PHP to check the conversations.author field. This works but I'm afraid when I get lots of data it will slow down.
I'm using the PHP MongoDB driver.
I have tried this..
$unread_conversations = $db->messages->find(
array(
'conversation.read'=>false
'conversation.author'=>array('$ne'=>$_SESSION['account']['_id']->__toString())
));
but thats not working because I want the messages that are not read and not an author.
This is not possible with regular mongo queries. You have to use map-reduce or mongos built in aggregation framework.
To accomplish your goal with current schema, you have to unwind nested list first.
Other solution is to change your schema and store each conversation as a separated document (with parent filed which contains the id of parent conversation).
And just as a side note: don't store id fields as string, always use ObjectId to store mongo ids.

Doctrine is making duplicated document entries

I am trying to insert a embedded document into my document with the following code.
// Add states, for the joining player.
$state = new PlayerState();
$state->setReady(false);
$state->setPlayer($player->getId());
$game->addPlayerState($state);
// Save element.
$dm->persist($game);
$dm->flush();
Problem being, that this generates 2 PlayerState Document like this.
{ "_id" : ObjectId( "513f50a58ead0ee9ac00000f" ),
"ready" : false,
"player" : "513f509f8ead0e8bac00000b" },
{ "_id" : ObjectId( "513f50af8ead0ecdac000015" ),
"ready" :false,
"player" : "513f509f8ead0e8bac00000b" }
Am i saving this in a incorrect way? Let me know, if you need more code.
This seemed to do the trick.
$state = new PlayerState();
$state->setReady(false);
$state->setPlayer($player->getId());
$dm->persist($state);
$dm->flush();
$game->addPlayerState($state);
// Save element.
$dm->flush();
This is hard to explain, but i will give it a try.
You need to persist the embedded document first, otherwise Doctrine will first persist the Document, making a embedded doc only with the values set, acting like a simple data container.
$state->setReady(false);
$state->setPlayer($player->getId());
After, doctrine will persist the embedded document once again, but this time looking at the Document object, assigning ID's, default values etc.
Resulting in 2 entries.

Categories