MongoDB php: find when element is present inside array - mongodb-php

I have following document structure
{
"_id":12638gkhF67JKGftyh88,
"tags":[1,3,5,6,9]
}
.
.
.
I want to search search on the basis where _id matches and tags has value '6'
in PHP, my query will be like
$collection -> find(
'$and' => array(
array("_id" => new MongoId("12638gkhF67JKGftyh88")),
array("tags" => WHAT WOULD BE HERE)
)
)
I couldn't find anything about this, help me out plz

Using the in operator
$collection -> find(
'$and' => array(
array("_id" => new MongoId("12638gkhF67JKGftyh88")),
array("tags" => array("$in" => "6"))
)
)

in mongodb there is an operator of in for searching values in arrays - http://docs.mongodb.org/manual/reference/operator/query/in/

Related

Drupal 8 - Absolute url in content

I'm migrating my website from dev environment to production environment so the absolute path url entered in CkEditor, Content or fields by users won't work on the domain.
What can I do?
Database can be huge so I'm looking for something else than search and replace in a 40 mo sql file.
I'm on Drupal 8 with mysql
You can simply find which tables/fields in db contain your absolute urls you want to replace. And then replace it in mysql. Here is an example:
$fields_to_update = [
['table' => 'field_data_body', 'field' => 'body_value'],
['table' => 'field_data_body', 'field' => 'body_summary'],
['table' => 'field_data_field_account_notes', 'field' => 'field_account_notes_value'],
['table' => 'field_data_field_extra_text', 'field' => 'field_extra_text_value'],
];
foreach ($fields_to_update as $item) {
$table = $item['table'];
$field = $item['field'];
db_query("UPDATE {$table} SET $field = REPLACE($field, 'http://www.example.com/', :new_name) WHERE $field LIKE BINARY '%http://www.example.com/%'", array(':new_name' => '/'));
}
hope it helps

How to SORT a SET and GET the full HASH

I'm new to Redis and I have to say I love it till now :)
I'm bumping into an issue I'm not sure how to solve it in the more efficient way.
I have a SET of HASH. Each HASH describe a post.
Here is the code to create and store the HASH:
// Create the HASH
$key = 'post:'.$post->getId();
$this->redis->hSet($key, 'created', $post->getCreated());
$this->redis->hSet($key, 'author', $post->getAuthor());
$this->redis->hSet($key, 'message', $post->getMessage());
// Store the HASH in the SET
$this->redis->sAdd('posts', $post->getId());
Now, previously I was storing all the post's attributes in a data field of the HASH (json_encoded) and I was fetching the information like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => 'post:*->data '
));
if (!is_array($data)) {
return array();
}
foreach ($data as &$post) {
$post = json_decode($post, true);
}
It was working great, I had all the posts information :)
But I had conflicts when updating the post in Redis (concurrent updates), so I've decided to have all the post's attributes in separated fields of the HASH and it fixed my issue of conflicts.
Now the problem I have is to fetch the HASH from my SET. Do I have to specify every single fields like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => array('post:*->created', 'post:*->author', 'post:*->message')
));
Or is there another way to fetch the full HASH directly within the SET?
I heard about pipeline but I'm not sure it's what I'm looking for and if I can use it with phpredis
Cheers, Maxime
UPDATE
I'm not sure I explained myself clearly. I have some elements in a set (post_id).
I want to get the first 10 posts of the SET, which means I want 10 hash (with all their fields and value) in order to build a post object.
I was previously storing all the object information in one field of the hash (data), now I have one field per attribute of the object.
before:
myHash:<id> data
now:
myHash:<id> id "1234" created "2010-01-01" author "John"
Before I was using SORT to fetch the top 10 posts (and paginate easily), like this:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array(0, 10),
'get' => 'post:*->data '
));
Now that I have X members to my hash I'm wondering what is the best solution.
Is it:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => 'post:*->data '
));
Or maybe:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => '#'
));
foreach($data as $post_id) {
$posts[] = $this->redis->hGetAll('post:'.$post_id);
}
Or finally:
$key = 'posts';
$data = $this->redis->sort($key, array(
'by' => 'nosort',
'limit' => array($offset, $limit),
'get' => '#'
));
$pipeline = $this->redis->multi();
foreach ($data as $post_id) {
$pipeline->hGetAll('post:'.$post_id);
}
return $pipeline->exec();
Or something else that I don't know yet?
What is the best, faster way to do this?
If you have read redis's source , you'll find that is not possible. There is a workaround that using lua script to combine 'sort' and 'hgetall' commands in a single redis invocation.
The 'get pattern' is processed by function 'lookupKeyByPattern'.
https://github.com/antirez/redis/blob/unstable/src/sort.c#L61
If you start with the redis.io documentation on hashes you'll find there are commands which allow you to get multiple hash members. In particular "HGETALL" for pulling all fields and values, or "HMGET" for pulling a set of fields with their values.
Additionally, for setting them I would recommend setting them in one pass with "HMSET"

Problems returning result of CDbCriteria based query

I have a query as follows
$criteria1 = new CDbCriteria();
$criteria1->condition = 'id = 1';
$modelA=Table1::model()->find($criteria1);
I can pass it to a view and return the title and entry
$this->widget('bootstrap.widgets.TbBox', array(
title' => $modelA['title'],
'content' => $modelA['entry'] ));
Now I'd like to return a range of entries
$criteria2 = new CDbCriteria();
$criteria2->condition = 'id > 7';
$modelB=Table1::model()->findAll($criteria2);
(btw : I'm following a form as laid out here). I was expecting to be able to read the resulting array of values out as below, but ['title'] is now being seen as a undefined index (obviously I'm expecting to read this out in a loop but you get the point)
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $modelB['title'][0],
'content' => $modelB['entry'][0]));
Where am I going wrong?
Thanks
No, the indexes should be specified in the different order: the number of a specific element first, then the name of the property. Additionally, it's better (=cleaner) to name the result of findAll so it'll show you (and any other reader) that it's a collection, not a single model:
$models = Table1::model()->findAll($criteria2);
// ...
$this->widget('bootstrap.widgets.TbBox', array(
'title' => $models[0]['title']
//...
));
But even that's not necessary if you use foreach (and you probably will):
foreach ($models as $model):
// ...
$this->widget('some.name', array(
'title' => $model['title']
);
endforeach;

WP_Query() and ordering items

I have to order items from wp_post by their menu_order (pages only).
I've written this line:
$query = new WP_Query();
$all = $query -> query(array('post_type' => 'page', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'DESC'));
$children = get_page_children($id, $all);
foreach ($children as $child) {
if ($child -> ID == get_the_id()) {
echo '<li class="active">' . $id . $child -> post_title . '</li>';
I see the items but they are not ordered.
Thanks.
FZ
I would say that the issue relates to the fact you are passing the $all object through get_page_children before using it in a loop.
Why don't you just forget get_page_children and add 'post_parent' to your list of WP_Query arguments?
$all = $query->query(array('post_type' => 'page', 'post_parent' => $id, 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'DESC'))
A helpful thread on Wordpress Stack Exchange;
https://wordpress.stackexchange.com/questions/35123/wp-get-all-the-sub-pages-of-the-parent-using-wp-query
EDIT.
To expand on comments. Sometimes there's confusion about menu_order - it does not relate to wp_nav_menus but to the Page Attributes Order input box, as shown below;

Symfony2 / Doctrine2 SQL Select Clause with Condition

I am creating a Form in Symfony2 and I would like to fill a dropdown with the results of a custom query. Here is an example php code:
<?php
public function buildForm(FormBuilder $builder, array $options)
{
$builder
//...
->add('type', 'entity', array(
'class' => 'EventBundle:Event',
'query_builder' => function (EntityRepository $er) {
return $er
->createQueryBuilder('e')
->add('select', 'e.id, CONCAT(IF (e.modified > NOW(), "Pending: ", ""), e.name) as name')
;
}
))
;
}
?>
I cannot find a way to set this SELECT clause though. I am looking to something similar to "new Zend_Db_Expr(...)" in Zend Framework.
Is there a way of achieving creating this query with the complex SELECT clause withoug typing it as native SQL code?
Thank you in advance!
Well, the query you're providing is supposed to be DQL, not SQL.
And seeing how IF() is not valid DQL, I'm not sure what you can do to fix this. Perhaps let the Entity class itself do the concatenation by way of the property option?
public function buildForm(FormBuilder $builder, array $options)
{
$builder
//...
->add('type', 'entity', array(
'class' => 'EventBundle:Event',
'property' => 'modifiedName',
))
;
}
And then in EventBundle\Entity\Event
public function getModifiedName()
{
return $this->modified > new \DateTime()
? 'Pending: ' . $this->getName()
: $this->getName()
;
}