Rebuilding arrays - php

I'm working on a tool that fetches stuff from the Wordpress database and handles it in different ways. One of the things I've done is build a simple array called $category, which contains the contents of wp_terms where term_id = <what the user picked>.
Unfortunately, it doesn't contain everything I want, so I've also populated $category->taxonomy with the relevant details from wp_term_taxonomy where term_id = <what the user picked>. It's a one-to-one relationship, so no problems there.
However, I've also got a bunch of stuff I need in wp_termsmeta, where there's a one-to-many relationship of multiple lines with the same term_id. So what I get is something like this:
{
"term_id" : 9813,
"name" : "Who's Who",
"slug" : "ww",
"term_group" : 0,
"taxonomy" :
{
"term_taxonomy_id" : 9832,
"term_id" : 9813,
"taxonomy" : "category",
"description" : "Who's Who is the CSICON Network's very own show about Doctor Who!",
"parent" : 0,
"count" : 58
},
"meta" : [
{
"meta_id" : 8490,
"terms_id" : 9813,
"meta_key" : "hosts",
"meta_value" : "1, 2"
},
{
"meta_id" : 8492,
"terms_id" : 9813,
"meta_key" : "thumbnail",
"meta_value" : "http://csicon.fm/wp-content/uploads/2015/12/ww_4-248x248.jpg"
}
]
}
We've got term_id, name, slug, and term_group from wp_terms in $category, then a bunch of stuff in $category->taxonomy and then a bunch of things under $category->meta.
And now for the problem.
If I want to access, say, the thumbnail URL, I'm going to have to traverse down to $category->meta[1]->meta_value, but I can't always know that it'll be [1]. For other categories, it might be [0] or [2]. All I know for sure is that it's the [n] that has meta_key = thumbnail.
Ideally, I would want a good way to iterate through meta and simply save the values for each meta_key as a "real" key under $category, so $category->thumbnail would return the meta_value currently stored there ... But I'll settle with a reliable way of always finding the right meta_value for a specific meta_key.
Any thoughts? :)
SOLVED
Thanks! Instead of $category['meta'] = Category::find($term_id)->catMeta;, I'm now running the following code, and it does exactly what I wanted.
$metaTemp = Category::find($term_id)->catMeta;
$metaTable = json_decode(json_encode($metaTemp), FALSE);
foreach($metaTable as $key => $value) {
$category[$value->meta_key] = $value->meta_value;
}

I would suggest converting meta from an array to an object where properties of that object would be meta_keys. So you get this structure:
{
"term_id" : 9813,
"meta" : {
"hosts" : {
"meta_id" : 8490,
"terms_id" : 9813,
"meta_key" : "hosts",
"meta_value" : "1, 2"
},
"thumbnail" : {
"meta_id" : 8492,
"terms_id" : 9813,
"meta_key" : "thumbnail",
"meta_value" : "http://csicon.fm/wp-content/uploads/2015/12/ww_4-248x248.jpg"
}
}
}
So that way search for the right meta would have a constant cost in time rather than linear.
your clients would search for it like so: $category->meta->hosts

Thanks! Instead of $category['meta'] = Category::find($term_id)->catMeta;, I'm now running the following code, and it does exactly what I wanted.
$metaTemp = Category::find($term_id)->catMeta;
$metaTable = json_decode(json_encode($metaTemp), FALSE);
foreach($metaTable as $key => $value) {
$category[$value->meta_key] = $value->meta_value;
}

Related

make a nameless array out 2 diferent tables with children in php

I have 2 tables in my DB. 1 is full with numbers (foreign keys) and other one is full of the data I need. This is how the array should (exactly) look
"array" : [
{
"data" : "blabla"
"data2" : "blabla"
"children" : [
{
"data" : "blabla"
"data2" : "blabla"
"children" : [
{
"data" : "blabla"
"data2" : "blabla"
}
]
},
{
"data" : "blabla"
"data2" : "blabla"
"children" : [
{
"data" : "blabla"
"data2" : "blabla"
}
]
}
]
}
]
and so on, so to say.. now the right order you can find in table 1,where it is lited what the mother ID is. and i need to get the data out of table 2 so be in the array. anyone knows how to do this? i am working in codeigniter
updated with pics:
To do that, you would need to process in two steps:
You fetch each document and it's data from the two tables (let's call them "documents" and "documents_data" to build a flat array of all the documents. This way you don't have to wonder where does the data go anymore :
$results = $this->db->query("SELECT d.*, dd.* FROM documents d LEFT JOIN documents_data dd ON dd.doc_id = d.doc_id");
$documents = $results->result_array();
Now that we have everything about each document, we just need to reorder them in a recursive array using a recursive function, that will call itself with the parent id for each children and build the tree :
function getDocumentTree($documents, $idParent = null)
{
$tree = [];
foreach($documents as $document) {
if($document['doc_doc_id'] == $idParent) {
$document['children'] = getDocumentTree($documents, $document['doc_id']);
$tree[] = $document;
}
}
return $tree;
}
$tree = getDocumentTree($documents);
Note: I haven't tested this code, this is just an idea on how it works, try to understand that (especially the concept of recursivity) and implement it by yourself.

Intelligent searching with mongo

I am using phalcon with mongodb. I have the following document in collection:
{
"_id" : ObjectId("547c8b6f7d30dd522b522255"),
"title" : "Test vacancy",
"slug" : "test-vacancy",
"location" : "the-netherlands",
"contract" : "fixed",
"function" : "Test vacancy",
"short_description" : "gdfsgfds",
"description" : "fdsafsdgfsdgdfa",
"promo_text" : "gfdsgdfs",
"company_name" : "gfdsgfsd",
"hits" : 36,
"updated_at" : 1.42685e+09,
}
In controller I am fetching all results by searched phase/query. For example I put example word and output will be all posts with example word in description or title or short_desc etc. Everything is correct but I want sort these posts in specific order. I mean if query will be same as title, this post should be first. Now it is somewhere below.
Can you help me? Thank you in advance.

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)
);

MapReduce for MongoDB on PHP?

I'm new to MongoDB and this is my first use of MapReduce ever.
I have two collections: Shops and Products with the following schema
Products
{'_id', 'type': 'first', 'enabled': 1, 'shop': $SHOP_ID }
{'_id', 'type': 'second', 'enabled': 0, 'shop': $SHOP_ID }
{'_id', 'type': 'second', 'enabled': 1, 'shop': $SHOP_ID }
And
Shops
{'_id', 'name':'L', ... }
{'_id', 'name':'M', ... }
I'm looking for a GROUPBY similar statement for MongoDB with MapReduce to retrieve the Shops with name 'L' that have Products with 'enabled' => 1
How can I do it? Thank you.
It should be possible to retrieve the desired information without a Map Reduce operation.
You could first query the "Products" collection for documents that match {'enabled': 1}, and then take the list of $SHOP_IDs from that query (which I imagine correspond to the _id values in the "Shops" collection), put them in an array, and perform an $in query on the "Shops" collection, combined with the query on "name".
For example, given the two collections:
> db.products.find()
{ "_id" : 1, "type" : "first", "enabled" : 1, "shop" : 3 }
{ "_id" : 2, "type" : "second", "enabled" : 0, "shop" : 4 }
{ "_id" : 3, "type" : "second", "enabled" : 1, "shop" : 5 }
> db.shops.find()
{ "_id" : 3, "name" : "L" }
{ "_id" : 4, "name" : "L" }
{ "_id" : 5, "name" : "M" }
>
First find all of the documents that match {"enabled" : 1}
> db.products.find({"enabled" : 1})
{ "_id" : 1, "type" : "first", "enabled" : 1, "shop" : 3 }
{ "_id" : 3, "type" : "second", "enabled" : 1, "shop" : 5 }
From the above query, generate a list of _ids:
> var c = db.products.find({"enabled" : 1})
> shop_ids = []
[ ]
> c.forEach(function(doc){shop_ids.push(doc.shop)})
> shop_ids
[ 3, 5 ]
Finally, query the shops collection for documents with _id values in the shop_ids array that also match {name:"L"}.
> db.shops.find({_id:{$in:shop_ids}, name:"L"})
{ "_id" : 3, "name" : "L" }
>
Similar questions regarding doing the equivalent of a join operation with Mongo have been asked before. This question provides some links which may provide you with additional guidance:
How to join MongoDB collections in Python?
If you would like to experiment with Map Reduce, here is a link to a blog post from a user who used an incremental Map Reduce operation to combine values from two collections.
http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/
Hopefully the above will allow you to retrieve the desired information from your collections.
Short answer: you can't do that (with a single MapReduce command).
Long answer: MapReduce jobs in MongoDB run only on a single collection and cannot refer other collections in the process. So, JOIN/GROUP BY-like behaviour of SQL is not available here. The new Aggregation Framework also operates on a single collection only.
I propose a two-part solution:
Get all shops with name "L".
Compose and run map-reduce command that will check every product document against this pre-computed list of shops.

MongoDB-PHP: JOIN-like query

Here are the objects:
courses
{ "name" : "Biology", "_id" : ObjectId("4b0552b0f0da7d1eb6f126a1") }
students
{
"name" : "Joe",
"classes" : [
{
"$ref" : "courses",
"$id" : ObjectId("4b0552b0f0da7d1eb6f126a1")
}
],
"_id" : ObjectId("4b0552e4f0da7d1eb6f126a2")
}
Using the PHP Mongo Class, how do I get all the students that has a biology course?
Thanks
You'll need to query twice. I dont have my environment in front of me, but something similar to what's below. I may have the "nested" portion of the second query incorrect.
// First grab the ID for the course.
$course = $collection->findOne(array("name" => "Biology"));
// Next query the students collection.
$collection->find(array("classes" => array("id" => $course['_id'])));

Categories