Removing specific items from array with MongoDB - codeigniter

I am developing a web app using Codeigniter and MongoDB.
The users can upload files and other users can comment on them.
I store the comments in an array called comments in the main file document.
This is all fine but how can I remove specific comments from the array?
I cannot use ID as key since a user can add multiple comments. How would
you recommend that I can do it?
This is my comment array:
"comments": [
{
"user_id": ObjectId("4f240b433dc7937d68030000"),
"user_name": "james",
"user_comment": "This is a comment",
"created_at": "2012-01-2821: 20: 44"
},
{
"user_id": ObjectId("4f240b433dc7937d68030000"),
"user_name": "mandy",
"user_comment": "This is another comment",
"created_at": "2012-01-2821: 31: 07"
}
],

If you can identify the comment item by matching userid, name or comment -- then you can remove that comment using update() command with $pull modifier along with the appropriate condition.
If you cannot do as above, include an unique id in the comments (like UUID).
To delete the comment, do the following:
db.coll.update({<cond to identify document}, {$pull: {'comments': {'name': <name>}}} )
If you use the id, which is preferred:
db.coll.update({<cond to identify document}, {$pull: {'comments': {'id': <id>}}} )

maybe you can remove comment by its 'created_at' time, as the time is unique.
$db.coll.update({cond to identify document},{$pull:{'comments':{'created_at':<>}}})

I think, you have add mongodb id to each comment when insert it. You can create a new mongodb id like this;
$comment_id = new MongoID();
Now, you can delete comments by id with $pull + $update like #smoorthy's answer.

Related

The filtered result I get by running the filter method on a laravel collection returns a new collection with an undesired index

To make it easier to understand the problem, I will hardcode the data that I am using the collection on and explain the problem.
Let us assume the following data structure in JSON format,
{
"shelters_with_linear_distances": [
{
"id": 3,
"shelterName": "Third Shelter",
"latitude": "5.0034000",
"longitude": "70.1230000",
"linear_distance": 3.1352984845527
},
{
"id": 4,
"shelterName": "Fourth Shelter",
"latitude": "5.1413000",
"longitude": "70.2250000",
"linear_distance": 2.7850629146201
},
{
"id": 5,
"shelterName": "Fifth Shelter",
"latitude": "5.2220000",
"longitude": "70.1320000",
"linear_distance": 2.6042789457753
}
]
}
The following filter method is run on a collection format of 'shelters_with_linear_distance' in the above data structure and $minimum_distance_to_a_shelter is a dynamically calculated value that holds a data type of double.
$nearest_shelter = $shelters_with_linear_distances_from_user
->filter(function ($shelter, $key) use ($minimum_distance_to_a_shelter) {
return $shelter['linear_distance'] == $minimum_distance_to_a_shelter;
});
The problem here is if I send back the value returned by the filter method (which is the $nearest_shelter) as JSON to the frontend,
in the postman I see the following output,
{
"nearest_shelter": {
"2": { // <------------------------------------ I can not figure out from where this key '2' is coming from.
"id": 5,
"shelterName": "Fifth Shelter",
"latitude": "5.2220000",
"longitude": "70.1320000",
"linear_distance": 2.6042789457753
}
}
}
The problem is I can not figure out from where the key I have pointed with an arrow in the above line of code is coming from.
*) It is okay if that value '2' never changes so that in the later parts of code I can always access the $nearest_shelter as $nearest_shelter['2']. But the problem is, the value of that key changes depending on the data I am receiving from the db.
One time that value of the key was '1', then once I added some new records to the db it was '2'. Also this one other time there was no key marked as either '1' or '2' and the shelter I wanted was directly inside the collection.
Can someone please help me understand why this is happening and how to get rid of that since I want to access the value inside the $nearest_shelter in latter parts of the code and I do not want to get a key like that which I do not know the value of beforehand to access the $nearest_shelter later in the code.
(Project I am working on uses laravel 5.2)
Thanks.
When you filter a collection, the index is preserved.
The "2" is because this element was the third (so index 2) in your original collection.
To fix this, just add ->values() after the filter:
$nearest_shelter = $shelters_with_linear_distances_from_user
->filter(function ($shelter, $key) use ($minimum_distance_to_a_shelter) {
return $shelter['linear_distance'] == $minimum_distance_to_a_shelter;
})->values();
This way the index will be reset and will start from 0, as usual.
From the documentation (for Laravel 5.2 as stated in your question) documentation:
The values method returns a new collection with the keys reset to consecutive integers

Send array to api via postman?

Beginner in API
I have table post_tag which is posts table has relation ( many to many ) with tags table.
my controller code ( every thing is good ):
$post = Post::create($data);
$post->tag()->attach($request->tags);
return $this->apiRespone($post , 'Added Post Successfuly', null ,200);
My question is here: now I send array of tags like that! Is that the best way or the correct way to send array ( means when I give this api url to mobile developer, he will know what to do with this api url ?
My way is correct or not ?
Although your solution works, a better approach since you are building an endpoint, it would be better to switch your input to accept JSON format rather than using form-data. Make your API endpoint to accept the following payload:
{
"title": "First Post",
"desc": "Desc of Post",
"image": "image3.jpg",
"category_id": 1,
"tags": [
"one",
"two",
"three"
]
}
In Laravel, you get just grab the tags (or any other properties) with the following:
$tags = $request->input('tags');
For the image, you can allow it to be received in base64 encoded image. The image will look like a bunch of string which should be converted by the client (ios or android) e.g:
{
image:"/9j/4AAQSkZJRgABAQAAAQABAAD/7QB8UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAF8cAigAWkZCTUQyMzAwMDk2OTAxMDAwMDgxNTIwMDAwNWY2MDAwMDA3NDZmMDAwMDE2YmEwMDAwNDAxYjAxMDBmMTM0MDEwMGY4YzIwMTAwZDkxNDAyMDA1ZDRhMDIwMAD/2wBDAAcHBwcHBwwHBwwRDAwMERcRERERFx4XFxcXFx4kHh4eHh4eJCQkJCQkJCQrKysrKysyMjIyMjg4O"
}
Then in PHP, if you want to save the image on disk, just use base64_decode. See example here.

Microsoft 365 API : Issue at attaching Contact to Campaign Response

I am trying to attach a contact to campaign response.
I am using rest API for that.
https://learn.microsoft.com/en-us/dynamics365/customer-engagement/web-api/campaignresponse?view=dynamics-ce-odata-9
Post Data :
{
"firstname": "TestFirst",
"lastname": "TestLast",
"emailaddress": "test#test.com",
"telephone": "1234567890",
"prioritycode": 0,
"responsecode": 1,
"subject": "Test Subject",
"statuscode": 1,
"regardingobjectid_campaign#odata.bind": "/campaigns(xxxx90c-11ef-e811-a966-000d3ad24a0d)",
"regardingobjectid_contact#odata.bind": "/contacts(xxxxfa2e-c3b5-e811-a962-000d3ad24a0d)"
}
Here is my JSON.
I am getting Error : “Campaign as RegardingObject must be supplied”. Without contact, it works fine.
I had the same problem and the documentation is not very clear about it, I had to check all the relationships of the CampaignResponse in order to understand how to solve this.
If you want to create a CampaignResponse linked to both a Campaign and a Contact you need to do the following:
Create a CampaignResponse with the "regardingobjectid_campaign#odata.bind" in the params sent.
POST "https://some_subdomain.crm6.dynamics.com/api/data/v9.0/campaignresponses"
{
"regardingobjectid_campaign#odata.bind": "/campaigns(CAMPAIGN_ID_HERE)",
"description": "some desc",
"subject": "some subject "
}
Then find the CampaignResponse you just created to get its activityid (every CampaignResponse is an Activity)
Finally, you need to create a new ActivityParty, that will link the Contact to the CampaignResponse.
POST "https://some_subdomain.crm6.dynamics.com/api/data/v9.0/campaignresponses(CAMPAIGN_ID_HERE)/activitypointer_activity_parties"
{
"partyid_contact#odata.bind": "/contacts(CONTACT_ID_HERE)",
"participationtypemask": 11 //this is the code for customers
}
The "Regarding" lookup field can only be set to a single "regarding" record. Even though it appears that there are different Regarding fields, one for each entity type, those are "helper" fields that let you easily set the main Regarding field by setting one of those regardingobjectid_xxx fields.
You must choose to use either a campaign or a contact as your Regarding field. You can of course create other lookups, so you could use the Regarding field for your campaign and then add an additional Contact lookup field, for example.

Changing data in every document

I am working on an application that has messages and I want to store all the messages. But my problem is the message has a from first name and last name which could change. So if for example my JSON was
{
"subject": "Hello!",
"message": "Hello there",
"from": {
"user_id": 1,
"firstname": "George",
"lastname": "Lastgeorge"
}
}
The user could potentially change their last name or even first name. Which would require basically looping over every record in elasticsearch and updating everyone with the user_id.
Is there a better way to go about doing this?
I feel you should use parent mapping.
Keep the user info as parent with userID as key.
/index/userinfo/userID
{
"name" : "George",
"last" : "Lastgeorge"
}
Next , you need to maintain each chat as a child document and map the parent to the userindo type.
This way , whenever you want to make some change to the user information , simply make the change in userInfo type.
With this feature intact , you can search your logs based on user information , or search users based on chat records.
Link - http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/parent-child.html

How do I return a hash with relational data using parse.com?

I have a Post class and I want to get the products associated to it. I'd like to write a single query that fetches all of the posts with the products associated to them. Below is a rough idea of what I'd like the hash to looks like.
Schema:
Post - objectId, title
PostItem - post(pointer), product(pointer)
Product - objectId, title, price
Output I want
{'results':
[{'objectId':'blah', 'title':'The Post',
'products':
[{'objectId':'14',
'title':'First product',
'price':'20'
},
{'objectId':'26',
'title':'Second product',
'price':'55'
}]
},
{'objectId':'blah2', 'title':'Second post',
[{'objectId':'38',
'title':'Some product',
'price':'54'
},
{'objectId':'26',
'title':'Another Product',
'price':'88'
}]
}]
}
Is this possible to do in one query? How would I do this using curl and parse.com?
If this is a many-to-many relationship, use a Parse relationship.
You'll want to use the include key option alongside pointers. Since it's been nearly a year since you posted, I assume you figured it out, but lurkers can read more about this (in Javascript) here.

Resources