Get Elasticsearch Score in Symfony - php

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

Related

MongoDB simply merge two unknown Documents

Is there a way in PHP Mongodb to write an object in an already existing document and only overwrite or add the values contained in the object.
The object structure is not known to me.
Here is a sample:
existing document:
{
"package": {
"parameter": "value",
"one": "two"
}
}
php object or array:
$obj[package][parameter] = "value2"
$obj[package][new] = "test"`
result schould be
{
"package": {
"parameter": "value2",
"one": "two",
"new": "test"
}
}
I need something like array_merge()
I tried the $merge aggerator but it does not seem to work.
Unknown modifier: $merge. Expected a valid update modifier or pipeline-style update specified as an array
$merge is used to insert/update document to collection, like the UPSERT command in SQL. Have a look at $mergeObjects. Use it in combination with $replaceWith (or $replaceRoot which is just an alias)
Would be something like
{ $replaceWith: { $mergeObjects: [ "$$ROOT", {"new" : "test"} ] } }
$$ROOT is the existing object. If the existing object has any fields with the same name as your new object, then it will be overwritten with new field values. If you like to prefer the existing fields, then flip the arguments in the array.
The sample data you provided is not valid JSON, thus I cannot provide a full solution.

JMSSerializerBundle and Symfony 2 - Output Doctrine/ODM to JSON file

I am trying to retrieve all records and display them in a JSON file.
My current function retrieves all Events that belong to a specific user.
/**
* create json files from doctrine/mongo
* #Route("/createjson", name="createjson")
*/
public function createJson()
{
// check user authentication
$this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');
$dm = $this->get('doctrine_mongodb')->getManager();
$repository = $dm->getRepository('AppBundle:Event');
$events = $repository->findBy(array('user' => $this->getUser()));
$serializer = SerializerBuilder::create()->build();
$result = $serializer->deserialize($events, 'AppBundle\Document\Event', 'json');
var_dump($result);
exit;
}
This is not working because some of the elements passed into the serializer are of an array format. Error I am getting.
Warning: json_decode() expects parameter 1 to be string, array given
500 Internal Server Error - ContextErrorException
However if I use the inbuilt Symfony Serializer it works fine:
$serializer = $this->container->get('serializer');
$reports = $serializer->serialize($events, 'json');
return new Response($reports);
However the JSON to be produced will be different to my Document/Entity hence why I want/need to use the JMSSerializerBundle.
For example, a record looks like this:
[{
"id": "572041b3288b560e5e00451c",
"name": "Test",
"date": "2016-04-27T05:25:00+1000",
"enddate": "2016-04-30T11:55:00+1000",
"location": {
"name": "Sydney, NSW"
},
"key": {
"id": "1g43g34g34g23f32g32G32gGSDF"
},
"user": {
"id": "57203174288b560e5e0044da"
}, ...
}]
But I only want to display (output) to JSON
[{
"id": "572041b3288b560e5e00451c",
"name": "Test",
"date": "2016-04-27T05:25:00+1000",
"location": "Sydney, NSW"
}]
How would I go about doing this? There is not much documentation on JMSSerializerBundle online.
Edit: I should mention that the database collection I am querying has a relation to the User collection which is managed by FOSUserBundle. I'm not sure if this has any relation to my problem however
You should look at the documentation of the bundle, may be you will find more information
http://jmsyst.com/bundles/JMSSerializerBundle
http://jmsyst.com/libs/serializer/master/usage
You seems to use the wrong function of the serializer. In your case, you seems to need to get a json from your user object, so you need to use
$serializer = SerializerBuilder::create()->build();
$result = $serializer->serialize($events, 'AppBundle\Document\Event', 'json');
serialize($object):string : get a string from an object
deserialize($string):object : get an object from a representation of an object (json, xml...).

Modify cake association result array

I am in a problem of modifying the cake association hierarchy,I am new to cakephp , below is the snippet of code.
Current Code
$this->Cateogory->find('all');
The output of the above expression is of the below form :
[
{
"Category": {
"id": "37",
"title": "Inner Title",
"color": "#ffffff",
"phone-number": ""
},
"CategoryHas": [],
"PhoneNumberhas": []
}
]
Requirement :-
I am creating API for third party consumption , now the third party has given the output format as below. I want the the output to be of below form.
[
{
"Category": {
"id": "37",
"title": "Inner Title",
"color": "#ffffff",
"phone-number": "",
"CategoryHas": [],
"PhoneNumberhas": []
}
}
]
I am searching on this problem for past 1 day and I consider that I need to make a custom PHP function to solve the problem.
Thanks in advance :
Just use a loop
To convert the array of the first format to an array of the second format - just use a loop e.g.:
foreach ($stuff as &$row) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
This would be appropriate to put in your controller if it's only needed in one place.
If you always, always want your results in that format, use an afterFind method (or a behavior) to implement the same logic:
// In the category model
public function afterFind($results, $primary = false) {
foreach ($results as &$row) {
if (isset($row['CategoryHas'])) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
}
if (isset($row['PhoneNumberhas'])) {
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
}
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
return $results;
}
Be wary of choosing this option - it means that your models act unconventionally, potentially meaning plugins don't work and other developers (or you, tomorrow) are confused by the way the models act.
Your association names are pretty strange. Why are they not better named? You can use proper names internally and reformat it when sending it.
If this is just about getting the API response into a silly format that doesn't provide additional benefit use JSON views and change the structure of the array in the view as needed. This section of the book explains it in detail, read it. Example taken from the book:
// Controller code
class CategoriesController extends AppController {
public function index() {
// ... get the categories
$this->set(compact('categories'));
}
}
// View code - app/View/Posts/json/index.ctp
foreach ($categories &$row) {
if (isset($row['CategoryHas'])) {
$row['Category']['CategoryHas'] = $row['CategoryHas'];
}
if (isset($row['PhoneNumberhas'])) {
$row['Category']['PhoneNumberhas'] = $row['PhoneNumberhas'];
}
unset($row['CategoryHas'], $row['PhoneNumberhas']);
}
echo json_encode(compact('categories'));
I would convince the client and bring some arguments for a proper response format and structure. Most clients usually don't know what they want. Sometimes you have smart asses who think they need something specific but can explain why. Check JSend or http://jsonapi.org/ on how to implement a proper API response format. Understand the reasons for these formats and bring these arguments to the client.

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 Group by Key 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

Categories