Cannot remove document in MongoDB using PHP driver - php

I am saving "Article" in MongoDB as bellow with _id of integers.
When I want to delete the article with the _id in php, nothing happens.
The code I use is:
$result = $db->arcitle->remove(
array("_id" =>intVal(41)),
array('safe' => true)
);
I have tried both with and without using "safe" option, neither works. When I echo $result, it is bool(true).
Any suggestion is much appreciated!
{ "_id" : 41,
"when" : Date( 1333318420855 ),
"publisher" : "5",
"title" : "10 Steps To The Perfect Portfolio Website",
"raw" : "",
"preview" : "",
"thumbnail" : "",
"content" : [
"{}" ],
"tags" : null,
"votes" : 0,
"voters" : [],
"comments" : [] }

you've got a spelling mistake in the collection name.
$result = $db->arcitle->remove(
Should probably be:
$result = $db->article->remove(array("_id" => 41));
The safe option will not confirm something was deleted, only that there was no error. Remove will not trigger an error deleting something that doesn't exist.
> db.foo.remove({_id: "I don't exist"})
> db.getLastError()
null
Note that you don't need to recast an integer as an integer - and if you do need to cast input as an integer - use a cast statement:
$string = "42";
$int = (int) $string; // $int === 42

Related

how to append information to a document in mongo?

Background Information
I have the following data in my mongo database:
{ "_id" :
ObjectId("581c97b573df465d63af53ae"),
"ph" : "+17771111234",
"fax" : false,
"city" : "abd",
"department" : "",
"description" : "a test"
}
I am now writing a script that will loop through a CSV file that contains data that I need to append to the document. For example, the data might look like this:
+17771111234, 10:15, 12:15, test#yahoo.com
+17771111234, 1:00, 9:00, anothertest#yahoo.com
Ultimately I want to end up with a mongo document that looks like this:
{ "_id" :
ObjectId("581c97b573df465d63af53ae"),
"ph" : "+17771111234",
"fax" : false,
"city" : "abd",
"department" : "",
"description" : "a test",
"contact_locations": [
{
"stime": "10:15",
"etime": "12:15",
"email": "test#yahoo.com"
},
{
"stime": "1:00",
"etime": "9:00",
"email": "anothertest#yahoo.com"
},
]
}
Problem
The code I've written is actually creating new documents instead of appending to the existing ones. And actually, it's not even creating a new document per row in the CSV file... which I haven't debugged enough yet to really understand why.
Code
For each row in the csv file, I'm running the following logic
while(!$csv->eof() && ($row = $csv->fgetcsv()) && $row[0] !== null) {
//code that massages the $row into the way I need it to look.
$data_to_submit = array('contact_locations' => $row);
echo "proving that the record already exists...: <BR>";
$cursor = $contact_collection->find(array('phnum'=>$row[0]));
var_dump(iterator_to_array($cursor));
echo "now attempting to update it....<BR>";
// $cursor = $contact_collection->update(array('phnum'=>$row[0]), $data_to_submit, array('upsert'=>true));
$cursor = $contact_collection->insert(array('phnum'=>$row[0]), $data_to_submit);
echo "AFTER UPDATE <BR><BR>";
$cursor = $contact_collection->find(array('phnum'=>$row[0]));
var_dump(iterator_to_array($cursor));
}
}
Questions
Is there a way to "append" to documents? Or do I need to grab the existing document, save as an array, merge my contact locations array with the main document and then resave?
how can I query to see if the "contact_locations" object already exists inside a document?
Hi yes you can do it !
1st you need to find your document and push the new value you need :
use findAndModify and $addToSet :
$cursor = $contact_collection->findAndModify(
array("ph" => "+17771111234"),
array('$addToSet' =>
array(
"contact_locations" => array(
"stime"=> "10:15",
"etime"=> "12:15",
"email"=> "test#yahoo.com"
)
)
)
);
The best part is $addToSet wont add 2 time the same stuff so you will not have twice the same value :)
Here the docs https://docs.mongodb.com/manual/reference/operator/update/addToSet/
I'm not sure the exact syntax in PHP as I've never done it before but I'm currently doing the same thing in JS with MongoDB and $push is the method you're looking for. Also if I may be a bit nitpicky I recommend changing $contact_collection to $contact_locations as a variable name. Array variable names are usually plural and being more descriptive is always better. Also make sure you find the array in the MongoDB first that you want to append to and that you use the MongoDb "update" command

How to search for a part of a word with ElasticSearch indices

I've recently started using ElasticSearch and I can't seem to make it search for a part of a word.
Example: I have three documents from my couchdb indexed in ElasticSearch:
{
"_id" : "1",
"name" : "John Doeman",
"function" : "Janitor"
}
{
"_id" : "2",
"name" : "Jane Doewoman",
"function" : "Teacher"
}
{
"_id" : "3",
"name" : "Jimmy Jackal",
"function" : "Student"
}
So now, I want to search for all documents containing "Doe"
curl http://localhost:9200/my_idx/my_type/_search?q=Doe
That doesn't return any hits. But if I search for
curl http://localhost:9200/my_idx/my_type/_search?q=Doeman
It does return one document (John Doeman).
Am trying with this url http://localhost/el/index.php?str=*doe*.
<?php
require 'vendor/autoload.php';
$client = Elasticsearch\ClientBuilder::create()->build();
$params = array();
$params['index'] = 's3';
$params['type'] = 's3files';
$params['body']['query']['match']['content'] = $_GET['str'];
$result = $client->search($params);
echo "<pre>";
print_r($result);
How can I make ElasticSearch find both John Doeman and Jane Doewoman when I search for "Doe" ?
You can simply try using a wildcard first:
curl http://localhost:9200/my_idx/my_type/_search?q=Doe*
If that's enough, you can get away with that. Otherwise, there are other more advanced solutions by creating custom analyzers with edge ngram tokenizers and filters.
You can Try this,Wildcard Query Matches documents that have fields matching a wildcard expression (not analyzed).
curl http://localhost:9200/my_idx/my_type/_search
{"query":
{
"wildcard" : { "name" : "doe*" }
}
}

PHP MongoDB query dynamic values

I want to query the content (text) inside my dynamic values keys, but i can't figure out the easiest way to do this.
So my mongo collection is like this:
{
"_id" : ObjectId("566aecb8f0e46491068b456c"),
"metadatas" : [
{
"schema_id" : "f645fabef0e464e51e8b4567",
"values" : {
"name" : "Test",
"age" : NumberLong(29),
"address" : "Test1"
},
"updated_on" : ISODate("2015-12-11T00:00:00Z")
},
{
"schema_id" : "d745fabef0e464e51e8b4567",
"values" : {
"something_else" : "lipsum"
},
"updated_on" : ISODate("2016-12-11T00:00:00Z")
}
],
}
How can i dynamically query whats inside my values since i cannot do $db->collec->find(array('metadatas.values.name' => $regex)) because i might have some other dynamic key instead of name?
thanks in advance
I ended up saving my keys uniquely on another collection and then building the query and concatenating it before applying based on #Sammaye idea:
$regex = new \MongoRegex("/^$query/i");
# First get all the dynamic keys you need to filter
$keys_to_search = $this->db->metadata_keys->find();
$this->log($keys_to_search);
$query_builder = array('$or'=>array());
foreach ($keys_to_search as $value){
array_push(
$query_builder['$or'],
array('metadatas.values.' . $value['key'] => $regex)
);
}
$this->log($query_builder);
$search_metadata_name = $this->db->filesfolders->find(
$query_builder, array('sql_fileid' => true)
);

How can you tell if a collection is capped?

I was using a PHP mongo command:
$db->command(array("create" => $name, "size" => $size, "capped" => true, "max" => $max));
And my collections grew way past their supposed capped limits. I put on a fix:
$db->createCollection($name, true, $size, $max);
Currently, the counts are so low I can't tell whether the 'fix' worked.
How can you tell if a collection is capped, either from the shell or PHP? I wasn't able to find this information in the system.namespaces.
Turns out there's also the isCapped() function.
db.foo.isCapped()
In the shell, use db.collection.stats(). If a collection is capped:
> db.my_collection.stats()["capped"]
1
If a collection is not capped, the "capped" key will not be present.
Below are example results from stats() for a capped collection:
> db.my_coll.stats()
{
"ns" : "my_db.my_coll",
"count" : 221,
"size" : 318556,
"avgObjSize" : 1441.4298642533936,
"storageSize" : 1000192,
"numExtents" : 1,
"nindexes" : 0,
"lastExtentSize" : 1000192,
"paddingFactor" : 1,
"flags" : 0,
"totalIndexSize" : 0,
"indexSizes" : {
},
"capped" : 1,
"max" : 2147483647,
"ok" : 1
}
This is with MongoDB 1.7.4.
From the shell:
db.system.namespaces.find()
You'll see a list of all collections and indexes for the given db. If a collection is capped, that will be indicated.
For PHP:
$collection = $db->selectCollection($name);
$result = $collection->validate();
$isCapped = isset($result['capped']);

MongoDB PHP nested documents

ok lets say i have this collection in my tv database
"season" : "1", "episodes" : {"code" : ["1x01", "1x02", "1x03"], "title" : ["Dont Look Back", "Genesis", "Third"]},
"season" : "2", "episodes" : {"code" : ["2x01", "2x02", "2x03"], "title" : ["D2ont Look Back", "G2enesis", "T2hird"]},
"season" : "3", "episodes" : {"code" : ["3x01", "3x02", "3x03"], "title" : ["D3ont Look Back", "G3enesis", "T3hird"]},
"season" : "4", "episodes" : {"code" : ["4x01", "4x02", "4x03"], "title" : ["D4ont Look Back", "G4enesis", "T4hird"]}
how do i make it so that only, lets say the episodes from season 2 are shown?
ive been trying using
echo $obj['episodes']['code'][0];
but it only shows episodes from the last row
im pretty sure my nesting is all wrong but im new to mongo and im having trouble trying to map this out
any advice?
You need to use find() first.
$a = $coll->findOne(array('season' => '2');
That will return an array $a which will have keys 'episodes', 'title'
So once you find the document with findOne, you would then just access the data using $a['title'] or whatever fields you need

Categories