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
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.
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.
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)
);
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.
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'])));