Any API to read Engagement Values? - sitecore

I am working on a solution where I need to read engagement values based on traffic types.
I tried with database query and it's working for me please see below code.
double totalValue = 0;
using (SqlConnection newCon = new SqlConnection(ConfigurationManager.ConnectionStrings["Analytics"].ConnectionString))
{
SqlCommand newCmd = new SqlCommand("SELECT SUM(Value) FROM Cache_TrafficByDay as totalValue WHERE (TrafficType = 20)", newCon);
newCon.Open();
SqlDataReader dr = newCmd.ExecuteReader();
while (dr.Read())
{
totalValue = Convert.ToDouble(dr[0]);
}
newCon.Close();
lblValue.Text = totalValue.ToString();
newCmd.ToString();
}
But I didn't find any API to do this where I can pass traffic type value and based on this traffic type value I can read engagement values.
Is there any direct method to read engagement values by passing traffic types?
Any help?
-Thanks,
Yogesh

The most recent Engagement Analytics API Reference (for 6.5 or later) doesn't list any obvious choices for accessing engagement value by traffic type.
It does however provide Sitecore.Analytics.Data.DataAccess.DataAdapters.SqlBase
This is an abstract class which contains methods to build custom queries.
Edit to provide code example:
string query ="SELECT SUM {0}Cache_TrafficByDay{1}.{0}Value{1} from {0}Cache_TrafficByDay{1} WHERE {0}Cache_TrafficByDay{1}.{0}TrafficType{1} = 20"
Double totalValue = DataAdapterManager.Sql.ReadOne<Double>(query, reader =>DataAdapterManager.Sql.GetDouble(0, reader),new object[0]);
I've not tested this, I've merely edited one of the example queries provided in the doumentation (see link above), and I'm not sure which method of ReadOne or ReadMany you need to do a SUM. You might also need to return a string using .GetString and cast it to a double yourself.

Related

Android Studio, DynamoDB Query using also sort key

I am having an issue where I am trying to get the data from the DynamoDB directly to my android studio. It works totally fine if I want to query with PK and filter with random column, however, no matter what I do I am unable to use also the sort key. Expression cannot be used as its part of partion key, but it is also not possible to put two primitive types into the query.
I also tried using QueryFilter, however, I am getting has protected access on the code bellow, even if I extend the class.
QueryFilter queryFilter = new QueryFilter();
This is the code which works for query with only Partion Key without Sort Key.
final Expression expression = new Expression();
expression.setExpressionStatement("#t < :time");
//expression.setExpressionStatement("begins_with (#t, :time)");
expression.withExpressionAttibuteValues(":time", new Primitive(timeNow.format(format)));
expression.addExpressionAttributeNames("#t", "time");
Search searchResult = dbTable.query(new Primitive("Location1"), expression);
After trying for a bit longer I have found a solution with QueryOperationConfig. As someone may find this usefull, I will be posting the solution which worked for me.
final Expression expression2 = new Expression();
expression2.setExpressionStatement("#p = :PK AND begins_with(#s, :SK)");
expression2.withExpressionAttibuteValues(":PK", new Primitive("Location1"));
expression2.withExpressionAttibuteValues(":SK", new Primitive("2021-04-11 22:08"));
expression2.addExpressionAttributeNames("#p", "location");
expression2.addExpressionAttributeNames("#s", "device # MAC # UUID");
QueryOperationConfig queryOperationConfig = new QueryOperationConfig();
queryOperationConfig.withKeyExpression(expression2);
Search searchResult = dbTable.query(queryOperationConfig);

Google App Engine KeyProperty

what's the benefits of KeyProperty ? if i can connect two entity using user_id and id
class User(ndb.Model):
name = ndb.StringProperty()
class Attend(ndb.Model):
user_id = ndb.IntegerProperty()
date = ndb.DateProperty()
User(id=1,name="xyz)
Attend(user_id = 1, date = "xyz")
There are a couple of minor benefits of storing a KeyProperty over an ID:
It is easier to do x.user_key.get() than ndb.Key(Attend, x.user_id).get()
The key is fully specified so there is no doubt about the entity it refers to but for the ID you also need to know the entity type.
These are both really minor so you can do either one. I sometimes store keys and sometimes store IDs based on other factors.

Prestashop Currency issue when try to get it using webservice

From Prestashop admin I have added new currency (currency which display values with comma like 26,51) and place an order. It shows prices in new currency (see image 1) but when I get order using web service, It does not get price in new currency with comma, It shows in dots instead of comma. (see image 2)
In PrestaShop database, the price values are stored as actual values (float numbers). To show them at any interface, PrestaShop passes the values to a predefined function and then display the output of that function only.
The function that Prestashop uses is
Tools::displayPrice()
You can also use it to convert the actual float value to the proper formatted currency value.
You would need to preprocess the value you get from the web service to apply the appropriate locale language:
$locale = ( isset($_COOKIE['locale']) ) ?
$_COOKIE['locale'] :
$_SERVER['HTTP_ACCEPT_LANGUAGE'];
function number_format_locale($number,$decimals=2) {
$locale = localeconv();
return number_format($number,$decimals,
$locale['decimal_point'],
$locale['thousands_sep']);
}
Use the function number_format_locale() to convert the total price to French.
French: bonne chance!
You can make a custom method that returns the value as you want, make an override of Order class (create a new php file in prestashop/override/classes/order named Order.php):
class Order extends OrderCore{
public function __construct($id = null, $id_lang = null){
$this->webserviceParameters['fields']['total_paid'] = array(
'getter' => 'getWsTotalPaid'
);
parent::__construct($id, $id_lang);
}
public function getWsTotalPaid(){
return str_replace('.', ',', $this->total_paid);
}
}
Obviously you can 'reformat' all fields that you want, but pay attention to parent settings.

Getting Lowest Used Price with Amazon API

I am using Django with Amazon API to receive books pricing. I NEED the Used Book Lowest Price. I keep getting the New Lowest Price showing. Below is the code my developer used. She said there is no way to get the Used Lowest Price. I have tried multiple different variations of the Offers/OfferSummary etc. Still not change. I also tried adding Response elements but no change... From what I read amazon always returns the Lowest New Price first and then the Lowested Used Price.
I am not great with coding but it looks like BeautifulSoup is just pulling the first amount that is shown. Any thoughts on how I can achieve this? Spent all day with changes and got no where getting the Used prices....
price_response = amazon.ItemLookup(ItemId=isbn, IdType="ISBN", SearchIndex="Books",
MerchantID="All", ResponseGroup="Small,OfferSummary")
try:
desc_soup = BeautifulSoup(price_response,"html.parser")
book_price = desc_soup.amount.get_text()
book_price =float( book_price)/100
book_price = decimal.Decimal(book_price)
price_range = []
Currently the code is just finding the first amount that it can. This should work:
desc_soup = BeautifulSoup(price_response)
book_price = desc_soup.lowestusedprice.amount.get_text()
You really shouldn't be using html.parser either given that the API response is XML. You should do this instead:
desc_soup = BeautifulSoup(price_response, 'xml')
book_price = desc_soup.LowestUsedPrice.Amount.get_text()
(Note the capitalisation of the tree objects changes. You also need lxml to be installed for this to work).

Searching a many to many database using Google Cloud Datastore

I am quite new to google app engine. I know google datastore is not sql, but I am trying to get many to many relationship behaviour in it. As you can see below, I have Gif entities and Tag entities. I want my application to search Gif entities by related tag. Here is what I have done;
class Gif(ndb.Model):
author = ndb.UserProperty()
link = ndb.StringProperty(indexed=False)
class Tag(ndb.Model):
name = ndb.StringProperty()
class TagGifPair(ndb.Model):
tag_id = ndb.IntegerProperty()
gif_id = ndb.IntegerProperty()
#classmethod
def search_gif_by_tag(cls, tag_name)
query = cls.query(name=tag_name)
# I am stuck here ...
Is this a correct start to do this? If so, how can I finish it. If not, how to do it?
You can use repeated properties https://developers.google.com/appengine/docs/python/ndb/properties#repeated the sample in the link uses tags with entity as sample but for your exact use case will be like:
class Gif(ndb.Model):
author = ndb.UserProperty()
link = ndb.StringProperty(indexed=False)
# you store array of tag keys here you can also just make this
# StringProperty(repeated=True)
tag = ndb.KeyProperty(repeated=True)
#classmethod
def get_by_tag(cls, tag_name):
# a query to a repeated property works the same as if it was a single value
return cls.query(cls.tag == ndb.Key(Tag, tag_name)).fetch()
# we will put the tag_name as its key.id()
# you only really need this if you wanna keep records of your tags
# you can simply keep the tags as string too
class Tag(ndb.Model):
gif_count = ndb.IntegerProperty(indexed=False)
Maybe you want to use list? I would do something like this if you only need to search gif by tags. I'm using db since I'm not familiar with ndb.
class Gif(db.Model):
author = db.UserProperty()
link = db.StringProperty(indexed=False)
tags = db.StringListProperty(indexed=True)
Query like this
Gif.all().filter('tags =', tag).fetch(1000)
There's different ways of doing many-to-many relationships. Using ListProperties is one way. The limitation to keep in mind if using ListProperties is that there's a limit to the number of indexes per entity, and a limit to the total entity size. This means that there's a limit to the number of entities in the list (depending on whether you hit the index count or entity size first). See the bottom of this page: https://developers.google.com/appengine/docs/python/datastore/overview
If you believe the number of references will work within this limit, this is a good way to go. Considering that you're not going to have thousands of admins for a Page, this is probably the right way.
The other way is to have an intermediate entity that has reference properties to both sides of your many-to-many. This method will let you scale much higher, but because of all the extra entity writes and reads, this is much more expensive.