MongoDB Group by Key PHP - php

Ok, so I have a collection in my MongoDB
here is a sample my key here is
company
{
"_id": ObjectId("4fdfe7b536314b4147000000"),
"company": "hoyts",
"barcode": "236602253",
"name": "Gold Class",
"logoURL": "http: \/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/ticketpic1.png",
"store_name": "movies"
}
Now the issue here is I have 4 rows/collects with hoyts, I need away to group them.
my current code
public function getstore($storename)
{
// select a collection (analogous to a relational database's table)
$collection = $this->db->products;
// find everything in the collection
$cursor = $collection->find(array("store_name"=>$storename));
$test = array();
// iterate through the results
while( $cursor->hasNext() ) {
$test[] = ($cursor->getNext());
}
//Print Results
print json_encode($test);
}
I tried using
group($key)->find
however that did not work.
Could someone give me a hand thanks

look at this example: http://php.net/manual/en/mongocollection.group.php

Related

Retrieve array object in a table from another table data id using a where clue in laravel

Question: I have two tables how to fetch a customer's data using order's table user_id
"order": [
{
"id": 1,
"user_id": 4
},
{
"id": 2,
"user_id": 5
}
],
"customers": [
{
"id": 5,
"name": "Mohamed Raazi",
"phone": "777",
}
],
Following code will return only the last object of an array, i need to display all the objects from user table using a where condition in customers table
for ($x=0; $x<count($orders); $x++){
$customer = User::where('id',$orders[$x]->user_id)->get();
}
I would use the ::whereIn-method where you can provide an array of IDs to and get all the users with the provided IDs.
First you would have to reformat the $orders array that you have so that it contains only user IDs. I am guessing that you are using Eloquent to fetch the orders, then you can use the pluck-function in your Eloquent-statement:
$userIds = Order::where('statement', true)->pluck('user_id')->toArray();
Please note that the where-statement is not real, I just want to illustrate how you can call the pluck-method.
Another alternative is that you use the map function on the $orders-collection and return only user IDs:
$userIds = $orders->map(function ($order) {
return $order->user_id;
});
Once you have your user IDs in an array/collection you can use it in the whereIn-statement:
$users = Users::whereIn('id', $userIds)->get();
Then this would give you all the users that that are connected to the orders you have in your order-collection.

Get Elasticsearch Score in Symfony

Elasticsearch provides a score field if you do a get request via cURL.
{
"_index": "twitter",
"_type": "tweet",
"_id": "123",
"_score": 4.2,
"firstName": "Max"
"lastName": "Mustermann"
}
Is there a way to get this score inside symfony. I am wondering if FOSElasticaBundle provides a function similar to the one below to get the score.
$finder = $this->container->get('fos_elastica.finder.app.article');
$boolQuery = new \Elastica\Query\BoolQuery();
$fieldQuery = new \Elastica\Query\Match();
$fieldQuery->setFieldQuery('title', 'I am a title string');
$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
$boolQuery->addShould($fieldQuery);
When searching with FOSElasticaBundle, you'll get a Elastica\ResultSet with Elastica\Result inside. You can iterate on those results, they have a getScore method to get what you need.
$resultSet = $this->store->search($query);
$results = $resultSet->getResults();
foreach ($results as $result) {
$score = $result->getScore();
}
Alternatively, you can get the score with this: $result->getParam('_score');
If trying to change this from within a class that extends FOS\ElasticaBundle\Repository, consider using $this->findHybrid(). That method returns an array containing HybridResult objects. Each HybridResult in turn contains both the transformed entity and the result data (including a score).

Laravel 5.4 array remove key index

In my controller, this statement generates an array:
// sort the region collection by continent for faster access in front end
$finalRegions = $regions->sortBy('continent_id');
{
"0":{
"id":1,
"name":"Alaska",
"image_x":227,
"image_y":117
},
"1":{
"id":5,
"name":"Australian Antartic Territory",
"image_x":1187,
"image_y":1037
....
}
}
How do I remove the index from the resulting object, so it looks like this:
[
{
"id":1,
"name":"Alaska",
"image_x":227,
"image_y":117
},
{
"id":5,
"name":"Australian Antartic Territory",
"image_x":1187,
"image_y":1037
....
}
]
This is stored in a field cast as json in the table class.
$res = [];
foreach ($finalRegions as $key => $value) {
$res[] = $value;
}
// $res contains desired result
Edit: Simple one liner (thanks to Jannie)
$res = array_values($finalRegions)
Since you have "Laravel" in your question title and it looks like you already have your regions in a Laravel Collection, there is an easier way. Just pipe your results through ->values() after the ->sortBy() clause like this:
$finalRegions = $regions->sortBy('continent_id')->values();
I still don't get why you need to remove those indexes, but you can do by this way.
<?php
$jsonArr = '{
"0":{
"id":1,
"name":"Alaska",
"image_x":227,
"image_y":117
},
"1":{
"id":5,
"name":"Australian Antartic Territory",
"image_x":1187,
"image_y":1037
}
}';
$decodeArr = json_decode($jsonArr, true);
print_r(json_encode($decodeArr));
This is just my idea, and you can edit part of your code where the query returns your JSON string.

elastica with terms and facets

I am faily new to elasticsearch and try to get along with elastica. I try to find out what Items are often togehter in a set of items when one of them is 2 and/or 7. So the index contains a lot of nested sets of items. The mutual items will be extracted with facets. But I don't seem to get the following query converted to elastica:
curl -X POST "http://localhost:9200/ratings/rating/_search?pretty=true" -d '
{
"query": {
"terms": {
"bookid": [2, 7],
"minimum_match" : 1
}
},
"size": 0,
"facets": {
"bookid": {
"terms": {
"field": "bookid"
}
}
}
}'
I was trying this:
// Load index
$index = $client->getIndex('ratings');
$type = $index->getType('rating');
// We want a Terms query.
$query = new Elastica_Query_Terms();
// Setting Terms
$query->setTerms('bookid', $bookids);
// Facets
$facet = new Elastica_Facet_Query('matches');
$facet->setField( 'bookid' )
->setSize(100);
$facet->setQuery($query);
$resultSet = $type->search($query);
return $resultSet;
but no luck so far. How do I add the facet properties?
Elastica query classes have an addFacet method, so rather than set the query on the facet, it makes more sense to add the facet to the query.
$facet = new Elastica_Facet_Query('matches');
$facet->setField('bookid')
->setSize(100);
$query = new Elastica_Query_Terms();
$query->setTerms('bookid', $bookids);
$query->addFacet($facet);

MongoDB & PHP get only product that matches barcode

I have this JSON and you can see under products i have barcodes for each product what i want to do is only get the information that matches the product barcode
{
"company": "village",
"logo": "http:\/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/villagetop.png",
"products": [
{
"barcode": "236690091",
"name": "Weekday",
"logo-URL": "http: \/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/ticketpic1.png",
"price": "12.50",
"discount": "1.50"
},
{
"barcode": "236690092",
"name": "Weekend",
"logo-URL": "http: \/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/ticketpic1.png",
"price": "13.50",
"discount": "1.60"
},
{
"barcode": "236690093",
"name": "Gold Class",
"logo-URL": "http: \/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/ticketpic1.png",
"price": "13.50",
"discount": "1.60"
}
],
"store_name": "movies"
}
for example If i hit 236690091 I only what the database (MongoDB) to return
"barcode": "236690091",
"name": "Weekday",
"logo-URL": "http: \/\/www.incard.com.au\/newsite\/template\/images\/movieticket\/4cinemas\/ticketpic1.png",
"price": "12.50",
"discount": "1.50"
not every product.
This is what I have tried
public function getbarcode($barcode)
{
// select a collection (analogous to a relational database's table)
$collection = $this->db->movies->products;
// find everything in the collection
$cursor = $collection->find(array("barcode" =>"{$barcode}"));
$test = array();
// iterate through the results
while( $cursor->hasNext() ) {
$test[] = ($cursor->getNext());
}
//Print Results
print json_encode($test);
}
You can't do this. MongoDB will always return the full document and will not allow you to return only a nested part that you want to search against. I would suggest to split out the products into its own collection, and then add the company info to each product. This will also circumvent the 16MB document limit in case you have lots of products for each company.
Without changing your schema, the following code should work:
public function getbarcode($barcode)
{
$products = array();
$collection = $this->db->movies->products;
foreach( $collection->find( array( 'products.barcode' => $barcode ) ) as $item )
{
foreach( $item->products as $product )
{
if ( $product['barcode'] == $barcode )
{
$products[] = $item;
}
}
}
return $products;
}
You can't do this the way you want. MongoDB will return only whole documents or some fields from the documents (if you specify them in query). You can't return only values that are matched by your query.
You can create a separate collection that will only hold the products objects (with a reference to a collection that holds the company data) where you can directly query for the product data you want.
If you can't / won't create another collection you can find all documents that have the product with specified barcode and filter them out using PHP.
For this second approach your query should be:
$collection->find(array("products.barcode" =>"{$barcode}"),
array('products' => 1));
With this query you're reaching into objects and returning only documents that have the barcode you are looking for.
Also, in this query you will only return the products property from your document and not the whole document. The products property will contain all the child objects, not just the one you are trying to find.
In your while loop you should check the values and filter them out properly.

Categories