php mongodb '$or' regex search - php

i'm trying to query mongodb "videos" collection to find results by "title" or "tags" fields... it keeps returning 0 results even when i search for terms i know are in the title and/or tags... any help would be appreciated
<?php
$user_query = preg_replace("/[[:blank:]]+/"," ", $_GET['q']);
$arr_query = explode(' ', $user_query);
foreach ($arr_query as $q) {
$title[] = '/'. $q .'/i';
$tags[] = '/'. $q .'/i';
}
$who=array(
'$or' => array(
array('$in' => array('$regex' => $title)),
array('$in' => array('$regex' => $tags))
)
);
$vids=$videos->find($who);
?>

You need to specify some fields for your $in:
$who=array('$or' => array(
array('somefield' => array('$in' => array(new MongoRegex($title)))),
array('otherotherfield' => array('$in' => array(new MongoRegex($tags))))
));
So it works by saying saying: if some field is in a range of some values
http://docs.mongodb.org/manual/reference/operator/in/
Edit
That might still not work because of the embedded $regex. If this is the case then you can try:
$who=array('$or' => array(
array('somefield' => new MongoRegex($title)),
array('otherotherfield' => new MongoRegex($tags))
));
Edit
If either of those queries don't work you can do:
$who = array('$or' => array());
foreach($arr_query as $q){
$who['$or'][] = array('title' => new MongoRegex("/^$q/"));
$who['$or'][] = array('tags' => new MongoRegex("/^$q/"));
}
Something like that should work, again it is untested but if my memory serves me right that should do it.
Another edit
This works perfectly for me:
$mongo = new Mongo();
$db = $mongo->tstvid;
$videos = $db->videos;
$videos->insert(array('title' => 'test1', 'tags' => array('h','h')));
$videos->insert(array('title' => 'test2', 'tags' => array('h','h')));
$videos->insert(array('title' => 'test3', 'tags' => array('h','h')));
$videos->insert(array('title' => 'tst3', 'tags' => array('h','test')));
$user_query = preg_replace("/[[:blank:]]+/"," ", "test");
$arr_query = explode(' ', $user_query);
if (count($arr_query) > 1) {
$who = array(
'$or' => array()
);
foreach ($arr_query as $q) {
$who['$or'][] = array('title' => new MongoRegex("/^". $q ."/i"));
$who['$or'][] = array('title' => new MongoRegex("/^". $q ."/i"));
}
} else {
$regex=new MongoRegex("/^". $user_query ."/i");
$tregex=new MongoRegex("/^". $user_query ."/i");
$who=array(
'$or' => array(
array('title' => $regex),
array('tags' => $tregex)
)
);
}
$vids=$videos->find($who);
$results="";
$i=0;
foreach($vids as $vid){
$results .= "<li>".$vid['title']."</li>\n";
$i++;
}
if($i==0){
$results="<em>No results found</em>";
}
echo $results;
And it outputs:
test1
test2
test3
tst3
So I am unsure what is wrong but I would recommend double checking your script is breaking up the keywords right and the schema is being searched right by issuing these queries in the console as well.
It should be noted I also tried this with:
$user_query = preg_replace("/[[:blank:]]+/"," ", "test h");
And it worked as well.

$search_string = preg_replace("/[^A-Za-z0-9]/", " ", $_GET['q']);
$search_string = $search_string;
//Connecting mongoDB
$dbhost = 'localhost';
$dbname = 'yourdbname';
$port = '27017';
$m = new MongoClient();
$db = $m->$dbname;
if($m){
// select a collection
$videos = $db->videos;
// search for title and tags
$searchQuery = array(
'$or' => array(
array(
'title' => array(
'$regex' => $search_string,
),
),
array(
'tags' => array(
'$regex' => $search_string,
),
),
)
);
$cursor = $videos->find($searchQuery);
foreach ($cursor as $doc) {
var_dump($doc);
//or what ever you want
//var_dump($doc['title']);
}
else{
echo "Collection videos cant select :( <br>";die();
}
Thinks this will help. :D

Related

PHP Convert single dimensional array to nested array

How do I convert an 'N' elements single dimensional array to 'N' level nested array in PHP ?
Example:
Input:
$input = array('Orange','Apple','Banana');
Expected Output:
$output = array(
'name' => 'Banana',
'sub_category' => array(
'name' => 'Apple',
'sub_category' => array(
'name' => 'Orange'
);
This is my code:
$categories = array('Orange','Apple','Banana');
$count = count($categories);
for($i=0;$i<=$count;$i++){
if(isset($categories[$i+1])){
$parent = $categories[$i+1]; // parent
$categories[$i+1]=array(
'name' => $categories[$i+1],
'sub_category' => array('name' => $categories[$i])
);
}
}
$categories = $categories[$count-1];
var_dump($categories);
My code is sloppy and I also get the following incorrect output:
$output = array(
'name' => 'Banana',
'sub_category' => array(
'name' => array(
'name' => 'Apple',
'sub_category' => array(
'name' => 'Orange'
);
);
Edit 1:
The problem/solution provided here does not seem to be answering my question.
You could use simple recursion technique:
function toNestedArray(array $input, array $result = [])
{
$result = ['name' => array_pop($input)];
if (count($input)) {
$result['sub_category'] = toNestedArray($input, $result);
}
return $result;
}
$categories = array('Orange','Apple','Banana');
$count = count($categories);
$categories2=array();
for($i=$count-1;$i>0;$i--){
if($i-2>-1){
$categories2=array(
'name'=>$categories[$i],
'sub_category'=>array('name'=>$categories[$i-1],'sub_categories'=>array('name'=>$categories[$i-2]))
);
}
}
echo "<pre>";
print_r($categories2);
echo "</pre>";
A simple option is to loop over the $input array, building the $output array from inside to out.
$output = array();
foreach ($input as $name) {
if (empty($output)) {
$output = array("name" => $name);
} else {
$output = array("name" => $name, "sub_category" => $output);
}
}

MongoDB Upsert not working in PHP

I am trying to run an update on my documents, I'm using upsert true but its still overwriting?
$col = "A" . $user->agencyID;
$db = $m->rules;
$collection = $db->$col;
$validValue = $_POST['validValue'];
$id = $_POST['ruleID'];
$document = array(
'tags' => array(
$validValue
)
);
$collection->update(
array(
'_id' => new MongoId($id)
),
array('$set' => $document),
array('upsert'=>true)
);
$validValue is like - Foo Bar
The first value goes in fine but when I try adding a different value it overwrites the first one?
I managed to figure out the problem, I needed $addToSet and also needed to take the array() from arround my $validValue
Actually, use $addToSet which will not push a value into the array if it already exists. This code is untested, please change to fit your needs.
$col = "A" . $user->agencyID;
$db = $m->rules;
$collection = $db->$col;
$validValue = $_POST['validValue'];
$id = $_POST['ruleID'];
$document = array(
'tags' => array(
$validValue
)
);
$collection->update(
array(
'_id' => new MongoId($id)
),
array('$addToSet' => array('tags' => $document))
);

Drupal submitting a query that change a tableselect

I'm new on drupal, i've create a module that shows a form with select, button submit and i've got a tableselect that lists some records (from database). the tableselect works and it's listing all records, but i want to "filter" records on this tableselect by selecting what i want to see with select list (and submitting). when i choose something in the select list and i submit, the tableselect dont change but if i execute a dsm($form['tableselect']) it said that tableselect contains what the db_query returns.
here is my form :
function myBook_form ($form, &$form_state){
$form = array();
$form['options_state'] = array(
'#type' => 'value',
'#value' => array (
'all'=>t('All'),
'Valid'=>t('Valid'),
'published'=>t('published'),
'not published'=>t('not published')
)
);
$form['state_book'] = array(
'#type' => 'select',
'#title' => t('state :'),
'#options' => $form['options_state']['#value'],
);
// filter submit button
$form['filter'] = array(
'#type' => 'submit',
'#value' => t('filter')
);
}
$header = array(
'book_title' => t('title'),
'book_state' => t('state'),
);
$sql = db_select('field_data_field_title','ta');
$sql->join('field_data_field_state','st','st.entity_id = ta.entity_id');
$sql
->fields('ta', array('field_title_value','entity_id'))
->fields('st',array('field_state_value'));
$result = $sql->execute();
$rows = array();
foreach ($result as $res){
$rows [] = array(
'book_title' => l($res->field_title_value, 'node/'.$res->entity_id),
'book_state' => $res->field_state_value
);
}
$form['table1'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('empty !'),
);
return $form;
here is my submit function :
function book_form_submit($form, &$form_state){
$cond = $form_state['values']['state_book'];
$header = array(
'book_title' => t('title'),
'book_state' => t('state'),
);
$sql = db_select('field_data_field_title','ta');
$sql->join('field_data_field_state','st','st.entity_id = ta.entity_id');
$sql
->fields('ta', array('field_title_value'))
->fields('st',array('field_state_value'));
$sql->condition('st.field_state_value', $cond, '=');
$quer = $sql->execute();
$rows = array();
foreach ($quer as $q){
array_push($rows, array(
'book_title' => $q->field_title_value,
'book_state' => $q->field_state_value,
));
}
$form['table2'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#empty' => t('empty!')
);
}
Thanks

Looping through results of a sql query

I have a query that returns multiple rows. I can't seem to find a way to store the rows in the $params array. Is there a way to loop throw and store each row in the $params variable
$aResult = $db->exec_sql($sql);
$params = array(
// where $aResult[o]'' would be row 1 [1] row 2 etc. //
'store_id' => $aResult[]['iStoreID'],
'user_id' => $aResult[]['iUserID'],
'store_name' => $aResult[]['cStoreName'],
'store_url' => $aResult[]['cStoreURL'],
'rid' => $aResult[]['cRID'],
'affiliate_id' => $aResult[]['iAffiliateID'],
'team_id' => $aResult[]['iTeamID'],
'bizOP' => $aResult[]['cDefaultBizOpp'],
'showBizOPp' => $aResult[]['iShowBizOppDropdown'],
'boPosting' => $aResult[]['iEnableBOPosting'],
'brandinglevel' => $aResult[]['iBrandingLevel']
);
thank you for your help
As simple as that:
$params = array();
foreach($aResult as $row) {
$params[] = array(
'store_id' => $row['iStoreID'],
'user_id' => $row['iUserID'],
'store_name' => $row['cStoreName'],
'store_url' => $row['cStoreURL'],
'rid' => $row['cRID'],
'affiliate_id' => $row['iAffiliateID'],
'team_id' => $row['iTeamID'],
'bizOP' => $row['cDefaultBizOpp'],
'showBizOPp' => $row['iShowBizOppDropdown'],
'boPosting' => $row['iEnableBOPosting'],
'brandinglevel' => $row['iBrandingLevel']
);
}
Without knowing the exact structure of the result array i guess you need something like this:
<?php
$params = array();
$mapping = array(
'store_id' => 'iStoredID',
'user_id' => 'iUserID',
// and so on...
);
foreach ($aResult as $row) {
$tempRow = array();
foreach ($row as $key => $value) {
$paramKey = isset($mapping[$key]) ? $mapping[$key] : $key;
$tempRow[$paramKey] = $value;
}
$params[] = $tempRow;
}
I use it like this
$aResult = mysql_query($sql);
while($data = mysql_fetch_array($result)) {
'store_id' = $aResult['iStoreID'];
}
At least that is the idea

Simple question on foreach loop question with array with 2 variables. (with code)

How can I edit this foreach loop so that I will be able to use strpos to look if q is found in the label ?
The result array will contain those values.
$q may be anna or ann or reas john
<?php
$q = $_GET["q"];
if (!$q) return;
$data = Array(
Array(
'label' => 'anna c13',
'category' => 'Products'
),
Array(
'label' => 'anders andersson',
'category' => 'People'
),
Array(
'label' => 'andreas johnson',
'category' => 'People'
)
);
$result = array();
foreach ($data as $value) {
array_push($result, array(
"label" => $value["label"],
"category" => $value["category"]
));
}
$json = json_encode($result);
echo $json;
?>
This will output every array in $data where $q is somewhere in 'label'.
<?php
if( !isset( $_GET["q"] )) return;
$q = $_GET["q"];
$data = Array(
Array(
'label' => 'anna c13',
'category' => 'Products'
),
Array(
'label' => 'anders andersson',
'category' => 'People'
),
Array(
'label' => 'andreas johnson',
'category' => 'People'
)
);
$result = array();
foreach ($data as $value) {
if( strpos( $value['label'], $q ) !== false ) {
$result[] = $value;
}
}
$json = json_encode($result);
echo $json;
?>
You haven't defined keys for your $data array - so it automatically take the form of:
array(
0=>array(...),
1=>array(...),
2=>array(...)
)
This means that you're using strtolower on an int - so that's probably why it's failing.
foreach ($data as $value) {
if(strpos($value['label'], $q) !== false){
$result[] = $value;
}
}

Categories