Text command will be removed > should use $text query instead - php

I've just set up MongoDB with last release of every components:
MongoDB 2.6.2
PHP 5.5.11 VC11
php_mongo.dll (I'm on windows) 1.4.3 ts VC11
I made a quick test to check if my DB is ok and I can retrieve my data using full text search:
$m = new MongoClient();
$db = $m->mytestdb;
$result = $db->command(
array(
'text' => 'items',
'search' => 'something',
'limit' => 50,
)
);
Everything is OK but when I see MongoDB logs there is one strange message I can't find any answers on the web:
[conn1] The text command will be removed in a future release. Use the $text query operator instead.
As I'm just starting to work on it it's kinda freaking me to know that the Full Text search I'm just using will be deprecated.
Even the official doc is using that code (see example #4).
So what should I use instead of my code? I'm afraid that if I use this code someday during an apt-get update & upgrade all my code will drop down.

I found out with the new $text from 2.6, here is how to do the same request as before with command:
$m = new MongoClient();
$db = $m->mytestdb;
$collection = $db->items;
$cursor = $collection->find(
array(
'$text' => array('$search' => 'something to search')
),
array (
'score' => array('$meta' => "textScore")
)
);

It seem's like they are rolling out $text in 2.6, and deprecating the text search feature.
you can reference more information of $text here.
http://docs.mongodb.org/manual/reference/operator/query/text/#op._S_text

Related

Add new field to a MongoDB document parsing from String to Int using updateMany

In my MongoDB collection, all documents contain a mileage field which currently is a string. Using PHP, I'd like to add a second field which contains the same content, but as an integer value. Questions like How to change the type of a field? contain custom MongoDB code which I don't want to run using PHP, and questions like mongodb php Strings to float values retrieve all documents and loop over them.
Is there any way to use \MongoDB\Operation\UpdateMany for this, as this would put all the work to the database level? I've already tried this for static values (like: add the same string to all documents), but struggle with getting the data to be inserted from the collection itself.
Some further hints:
I'm looking for a pure PHP solution that does not rely on any binary to be called using exec. This should avoid installing more packages than needed on the PHP server
Currently, I have to use MongoDB in v4.0. Yes, that's not the most recent version, but I'm not in the position to perform an upgrade
Try this, please:
01) MongoDB Aggregate reference:
db.collectionName.aggregate(
[
{ "$addFields": {
"intField": { "$toInt": "$stringFieldName" }
}},
{ "$out": "collectionName" }
]
)
02) Possible PHP solution (Using as reference https://www.php.net/manual/en/mongocollection.aggregate.php):
$pipeline = array(
array(
'$addFields' => array(
'integerField' => array('$toInt' => '$mileage')
)
),
array(
'$out' => 'collection'
),
);
$updateResult = $collection->aggregate(pipeline);
You could use $set like this in 4.2 which supports aggregation pipeline in update.
$set stage creates a mileageasint based on the previous with $toInt value
db.collection.updateMany(
<query>,
[{ $set: { "mileageasint":{"$toInt":"$mileage" }}}],
...
)
Php Solution ( Using example from here)
$updateResult = $collection->updateMany(
[],
[['$set' => [ 'mileageasint' => [ '$toInt' => '$mileage']]]]
);

Elasticsearch boosting syntax PHP

I did read the elasticsearch documentation but it lacks examples, for me.
I have put some documents in the es-engine, they contain the field "text" and "title".
Now I want to boost up the hits in the field "title". I'm using the php-api.
I tried this one:
$params_ci['index'] = 'all';
$params_ci['type'] = 'all';
$params_ci['body']['query']['query_string']['query'] = $query;
$params_ci['body']['function_score']['functions']['field_value_factor'] = array('field' => 'title',
'factor' => 1.2)
$client = ElasticClientFactory::build();
$client->search($params_ci)
But I get an error. Without the "function_score" it works.
... Parse Failure [No parser for element [function_score] ...
The biggest problem for me is how to translate the JSON in the documentation into the right place as arrays. I know JSON is like an array but often it fits not in my hierarchy of array?
Uses ElasticSearch Version: elasticsearch-1.1.1
The right synax is:
$params_ci['body']['query']['function_score']['functions']['field_value_factor'] = array('field' => 'title', 'factor' => 1.2)

MongoDb delete by parametr

I try NoSQL.
I know how delete by id
$criteria = array(
'_id' => new MongoId('5277aeb6b28fada80a00002b'),
);
$users->remove($criteria);
but how to delete if you new for example value, like "name"="John"
You have to do absolutely the same thing as you have done with _id field:
$users->remove(array(
'name' => 'John'
));
You can always look at mongodb php documentation to find how to transform mongodb shell code to php.
I don't now how it is represented in PHP, but in Scala you would do something like this:
val criteria = MongoDBObject("name" -> "John")
coll.remove(criteria)

ZF2 Zend\Db Insert/Update Using Mysql Expression (Zend\Db\Sql\Expression?)

Is there any way to include MySQL expressions like NOW() in the current build of ZF2 (2.0.0beta4) through Zend\Db and/or TableGateway insert()/update() statements?
Here is a related post on the mailing list, though it hasn't been answered: http://zend-framework-community.634137.n4.nabble.com/Zend-Db-Expr-and-Transactions-in-ZF2-Db-td4472944.html
It appears that ZF1 used something like:
$data = array(
'update_time' => new \Zend\Db\Expr("NOW()")
);
And after looking through Zend\Db\Sql\Expression I tried:
$data = array(
'update_time' => new \Zend\Db\Sql\Expression("NOW()"),
);
But get the following error:
Catchable fatal error: Object of class Zend\Db\Sql\Expression could not be converted to string in /var/www/vendor/ZF2/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 256
As recommended here: http://zend-framework-community.634137.n4.nabble.com/ZF2-beta3-Zend-Db-Sql-Insert-new-Expression-now-td4536197.html I'm currently just setting the date with PHP code, but I'd rather use the MySQL server as the single source of truth for date/times.
$data = array(
'update_time' => date('Y-m-d H:i:s'),
);
Thanks, I appreciate any input!
Zend_Db_Sql_Expression works for me now.
$data = array(
'update_time' => new \Zend\Db\Sql\Expression("NOW()"),
);
I am not sure if they fixed this in the latest updates, but it was a know bug and even if they said it was fixed, for me it still didn't work after the fix.
It works for me too. Maybe, your problem was like mine. The string error conversion was because the parameter that I passed to method was elements of array and not the array. Check this and have sure that you are passing $object->method($array).
You can try:
\Zend\Db\Sql\Predicate\Literal();
//or
\Zend\Db\Sql\Literal();
------------------------------------
$data = array(
'update_time' => new \Zend\Db\Sql\Literal("NOW()"),
);
https://framework.zend.com/manual/2.2/en/modules/zend.db.sql.html#literal-literal

Use of "$or" condition is not working

I am developing a search portal, so I need to find the searched text on more than one field.
I am trying to use the advanced query of MongoDB in PHP.
My code is:
$mongo = new MongoDBCONN();
$jobCollection = $mongo->select('jobs', $mongo);
$advanceQuery=array('orgId' => '21')
$query_q=array('$or'=>array(
array("jobTitle"=>new MongoRegex("/$search/i")),
array("jobLocationCity"=>new MongoRegex("/$search/i")),
array('jobLocationCountry'=>new MongoRegex("/$search/i"))
));
$advanceQuery=array_merge($advanceQuery,$query_q);
$jobCollection->find($advanceQuery);
It returns NULL every time, whereas MongoRegex is working fine, because when I use it to search on only one field it works.
$search is post as input text.
I found the answer on my own, actually this was a version problem. I was using 1.4.4, but after update to 1.7.4 it is working. On the mongo website I found that the "or" operator was included only from version 1.7.x onwards.
$regexObj = new MongoRegex("/$search_term/i");
$where = array(
'$or' => array(
array("Name" => $regexObj),
array("image.caption.text" => $regexObj),
array("image.user.username" => $regexObj)
)
);
$cursor = $collection->find($where);
// Parsing the results
while ($cursor->hasNext())
{
$obj = $cursor->getNext();
$profile_image = $obj['image']['user']['profile_picture'];
}
If you need to combine the regex with another operator, you need to use the $regex clause. That one is missing in your code example. Please read again about how to query with regulars expressions.

Categories