Watson conversation list entity value - ibm-watson

In Watson Conversation when I create a dialog, can I list the values of my Entity?? for sample I have one entity fruits (apple, orange, and etc) so in one of my responses can I list the content of #fruits??
tks

For access intents and entities, first, your user need to request something for calling this objects... And in this case, your application will access:
Name of entity (#fruits);
The value of your entity typed from your user
Your app will show Fruit:orange if you user type orange, and Watson will recognize the entity and the value and save inside entities.fruit[0], not all values from your entity inside #fruits, like this.
Access entity: IBM Official Documentation.
Anyway: I think you want all values. Right?
I guess that best form is using context variables to save all "fruits" and show like:
For this Dialog runtime context:
{
"context": {
"toppings_array": ["orange", "apple"]
}
}
Update:
{
"context": {
"toppings_array": "<? $toppings_array.append('banana', 'melon') ?>"
}
}
Result:
{
"context": {
"toppings_array": ["orange", "apple", "banana", "melon"]
}
}
Show for the user:
{
"output": {
"text": "This is the array: <? $toppings_array.join(', ') ?>"
}
}
All JSON Example:
{
"context": {
"fruits": [
"lemon",
"orange",
"apple"
]
},
"output": {
"text": {
"values": [
"This is the array: <? $fruits.join(', ') ?>"
],
"selection_policy": "sequential"
}
}
}
Result:
This is the array: lemon, orange, apple
See the official example from Official Documentation.

Related

Alexa Spelling Skill - How to trigger answer intent when a word is misspelledc

I am currently writing a alexa spelling skill to ask different spellings and to check user input according to the data we have. I created below intents & slots to do the expected work:
Intents:
SpellingIntent - Ask a random word from the list of words
AnswerIntent - Validate the user input
Slots:
Words - to keep track of all the words
Spellings - Spellings of words in dot separated format
For example if the word is apple, then spellings slot would have a.p.p.l.e
My app is working fine if the user spelled the word correctly, but if the user misspelled the word then I am not getting event till answerIntent to validate.
I researched about this and I found that amazon deprecated Amazon.LITERAL built in slot type to trigger any word spoken by user and I have to use SearchQuery. But I am not getting how to get the event fired to my answer intent whatever the user said.
Could anyone help me out to figure this?
I haven't tested this but I would suggest trying the following as a solution.
1 - Stop using AMAZON.SearchQuery, instead define a custom slot value like the below:
{
"types": [
{
"name": "LETTER",
"values": [
{
"name": {
"value": "a",
"synonyms": []
}
},
{
"name": {
"value": "b",
"synonyms": []
}
},
{
"name": {
"value": "c",
"synonyms": []
}
},
// ... and so on
]
}
]
}
2 - Redefine your AnswerIntent to accept varying quantities of the LETTER slot value, like the below:
{
"intents": [
{
"name": "AnswerIntent",
"slots": [
{
"name": "LetterOne",
"type": "LETTER"
},
{
"name": "LetterTwo",
"type": "LETTER"
},
{
"name": "LetterThree",
"type": "LETTER"
},
// ... and so on
],
"samples": [
"{LetterOne}",
"{LetterOne} {LetterTwo}",
"{LetterOne} {LetterTwo} {LetterThree}",
// ... and so on
]
}
]
}
In theory, this set up should trigger the AnswerIntent any time a user speaks a sequence of letters. You should then be able to collect the letters passed through in slot values and compare them against the correct spelling.
As a potential additional step you could try adding synonyms to the slot values for phonetically matching words such as the below. Then access the slots in your code via the key value.
{
"name": {
"value": "b",
"synonyms": [
"be",
"bee"
]
}
}

Watson conversation service validation

Is there any way of validating the user input which uses context variable?
My context variable stores the email address,so I would like the validation to check for the "#" sign.
Is there any way of doing this?
You can use the context variable with regex to extract the e-mail address, and after your code just validate the information, if the variableEmail = context.mail, do it... I cant help you with the code because you did not report your Programmation language.
But, if you want to saves the mail address in a context variable.
I made a conversation example so you know how to do it, here are the steps:
Part I:
Part II:
Part III:
The JSON files
Name example:
{
"context": {
"name": "<? input.text?>"
},
"output": {
"text": {
"values": [
"Hi $name, please report your e-mail address."
],
"selection_policy": "sequential"
}
}
}
Mail example:
{
"context": {
"mail": "<? input.text.extract('[a-zA-Z0-9._%+-]+#[a-zA-Z0-9.-]+(\\.[a-zA-Z]+){1,}',0) ?>"
},
"output": {
"text": {
"values": [
"Thanks very much, your name is $name and your mail is $mail."
],
"selection_policy": "sequential"
}
}
}
And finnaly, the result is:
If you want knows how to validate mail, search with the programming language you are developing the application and don't forget: the informations is saved inside: context.name or context.mail, according to my example.

Update array of subdocuments in MongoDB

I have a collection of students that have a name and an array of email addresses. A student document looks something like this:
{
"_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
"name": "John Doe",
"emails": [
{
"label": "private",
"value": "private#johndoe.com"
},
{
"label": "work",
"value": "work#johndoe.com"
}
]
}
The label in the email subdocument is set to be unique per document, so there can't be two entries with the same label.
My problems is, that when updating a student document, I want to achieve the following:
adding an email with a new label should simply add a new subdocument with the given label and value to the array
if adding an email with a label that already exists, the value of the existing should be set to the data of the update
For example when updating with the following data:
{
"_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
"emails": [
{
"label": "private",
"value": "me#johndoe.com"
},
{
"label": "school",
"value": "school#johndoe.com"
}
]
}
I would like the result of the emails array to be:
"emails": [
{
"label": "private",
"value": "me#johndoe.com"
},
{
"label": "work",
"value": "work#johndoe.com"
},
{
"label": "school",
"value": "school#johndoe.com"
}
]
How can I achieve this in MongoDB (optionally using mongoose)? Is this at all possible or do I have to check the array myself in the application code?
You could try this update but only efficient for small datasets:
mongo shell:
var data = {
"_id": ObjectId("56d06bb6d9f75035956fa7ba"),
"emails": [
{
"label": "private",
"value": "me#johndoe.com"
},
{
"label": "school",
"value": "school#johndoe.com"
}
]
};
data.emails.forEach(function(email) {
var emails = db.students.findOne({_id: data._id}).emails,
query = { "_id": data._id },
update = {};
emails.forEach(function(e) {
if (e.label === email.label) {
query["emails.label"] = email.label;
update["$set"] = { "emails.$.value": email.value };
} else {
update["$addToSet"] = { "emails": email };
}
db.students.update(query, update)
});
});
Suggestion: refactor your data to use the "label" as an actual field name.
There is one straightforward way in which MongoDB can guarantee unique values for a given email label - by making the label a single separate field in itself, in an email sub-document. Your data needs to exist in this structure:
{
"_id": ObjectId("56d06bb6d9f75035956fa7ba"),
"name": "John Doe",
"emails": {
"private": "private#johndoe.com",
"work" : "work#johndoe.com"
}
}
Now, when you want to update a student's emails you can do an update like this:
db.students.update(
{"_id": ObjectId("56d06bb6d9f75035956fa7ba")},
{$set: {
"emails.private" : "me#johndoe.com",
"emails.school" : "school#johndoe.com"
}}
);
And that will change the data to this:
{
"_id": ObjectId("56d06bb6d9f75035956fa7ba"),
"name": "John Doe",
"emails": {
"private": "me#johndoe.com",
"work" : "work#johndoe.com",
"school" : "school#johndoe.com"
}
}
Admittedly there is a disadvantage to this approach: you will need to change the structure of the input data, from the emails being in an array of sub-documents to the emails being a single sub-document of single fields. But the advantage is that your data requirements are automatically met by the way that JSON objects work.
After investigating the different options posted, I decided to go with my own approach of doing the update manually in the code using lodash's unionBy() function. Using express and mongoose's findById() that basically looks like this:
Student.findById(req.params.id, function(err, student) {
if(req.body.name) student.name = req.body.name;
if(req.body.emails && req.body.emails.length > 0) {
student.emails = _.unionBy(req.body.emails, student.emails, 'label');
}
student.save(function(err, result) {
if(err) return next(err);
res.status(200).json(result);
});
});
This way I get the full flexibility of partial updates for all fields. Of course you could also use findByIdAndUpdate() or other options.
Alternate approach:
However the way of changing the schema like Vince Bowdren suggested, making label a single separate field in a email subdocument, is also a viable option. In the end it just depends on your personal preferences and if you need strict validation on your data or not.
If you are using mongoose like I do, you would have to define a separate schema like so:
var EmailSchema = new mongoose.Schema({
work: { type: String, validate: validateEmail },
private: { type: String, validate: validateEmail }
}, {
strict: false,
_id: false
});
In the schema you can define properties for the labels you already want to support and add validation. By setting the strict: false option, you would allow the user to also post emails with custom labels. Note however, that these would not be validated. You would have to apply the validation manually in your application similar to the way I did it in my approach above for the merging.

How do I get and set model data that's nested deep in Backbone?

I have this model and I want to update the team value when I gather the correct info on a form submit but I'm not sure how to the specific team. I know in backbone I can use the model to get teams but I'm not sure how to then go from teams into the correct team using the code attribute?
I've tried:
// My new team to replace team in code EFU"
var newTeam: {
"id": "POS-876",
"name: "Swansea City"
}
var teams = this.model.get('teams');
var selectedTeam = teams.get('EFU'); // I know this is wrong
selectedTeam.set('team', newTeam);
I'm not sure how I target the correct team then update the team details?
Model
{
"id": "4V6",
"name": "Premier League",
"teams": [{
"code": "EFU",
"team": {
"id": "POS-1",
"name": "Manchester United"
}
}, {
"code": "BMD",
"team": {
"id": "POS-223",
"name": "Chelsea"
}
}]
}
Your Model is a bit confusing. Why is it wrapped in array brackets? And why are you getting 'exchanges' instead of 'teams'? And should perhaps teams be a collection instead of a simple array?
But in any case, to find the specific team, you can use Underscore.
var selectedTeam = _.findWhere(teams, {code: 'EFU'});

When do the Facebook graph api endpoints return an array wrapped in a { data: ... } object?

Some Facebook graph api endpoints return arrays like this:
"likes": {
"data": [
{
"id": "000000",
"name": "Somebody"
}
],
"paging": {
"cursors": {
"after": ".....",
"before": "....."
}
}
}
While others return arrays like this:
"actions": [
{
"name": "Comment",
"link": "https://www.facebook.com/000000/posts/00000"
},
{
"name": "Like",
"link": "https://www.facebook.com/00000/posts/00000"
}
]
Does anyone know of where in the documentation Facebook explains when an array is going to be returned wrapped in a { data: [...] } object? As far as I know, facebook just lists everything that is an array as array and doesn't explain when a data object will be returned.
I guess I can assume that if something can be "paged" that it will be in a data structure...
Am I missing some documentation about Facebook data types somewhere?
You are right, they seem to list everything that is an array as array.
For instance, in the documentation for the Post Endpoint, the return type for both "likes" and "actions" is listed as an array.
Likes
...
Array of objects containing the id and name fields.
Requesting with summary=1 will also return a summary object
containing the total_count of likes.
Actions
...
Array of objects containing the name and link
I think that's why you have to query the actual end point, and inspect the JSON (like you are doing) and figure out what is actually coming back.
No wonder the Facebook API is the proud winner of the "Worst API" Award!
Any feed(feeds/posts)(that is every array) you retrieve will be retured in data object, inside this data object the array will be there.Also the friend list is embedded in data object,which will have array of objects. Something like this:
{"data": [
{
"id": "..",
"name": ".."
}
],
"paging": {
"cursors": {
"after": ".....",
"before": "....."
}
}
}
While in all other api requests , which do not return an array, have structure like this:
{
"id": "..",
"name": ".."
}

Resources