Orion Context Broker How to filter an object by name contains a keyword - fiware-orion

We are using Orion Context Broker as our database.
Recently, We have meet an requirement that user want to find a City by name of this City container a keyword.
For example:
We have city name likes this. Hanoi, Madrid, London, Barcelona, Paris, Lyon.
If user type: "on", we should show Lyon, London.
The city object like this.
{
"type": "City",
"isPattern": "false",
"id": "city1",
"attributes": [
{
"name": "name",
"type": "string",
"value": "London"
}
]
}
So I am wondering if any queryContext filtering can help us to sort out this case.
I have done some research and there is no good sounds on this.
Many thanks.

You can use idPattern in GET /v2/entities which value is a regular expression. Thus the following query:
GET /v2/entities?idPattern=on
should return any City with the "on" substring in its id.
EDIT: if you want to apply a pattern to the value of some attribute, then you have to use q query parameter and the ~= NGSIv2 Simple Query Operator. Something like this:
GET /v2/entities?q=colour~=or

I have figured out that we use ~= operation to do that.
Please see the follow quote.
Match pattern: ~=. The value matches a given pattern, expressed as a regular expression, e.g. color~=ow. For an entity to match, it must contain the target property (color) and the target property value must match the string in the right-hand side, 'ow' in this example (brown and yellow would match, black and white would not). This operation is only valid for target properties of type string.
http://telefonicaid.github.io/fiware-orion/api/v2/stable/
Section: Simple Query Language
Many thanks.

Related

Convert Row Count to INT in Azure Data Factory

I am trying to use a Lookup Activity to return a row count. I am able to do this, but once I do, I would like to run an If Statement against it and if the count returns more than 20MIL in rows, I want to execute an additional pipeline for further table manipulation. The issue, however, is that I can not compare the returned value to a static integer. Below is the current Dynamic Expression I have for this If Statement:
#greater(int(activity('COUNT_RL_WK_GRBY_LOOKUP').output),20000000)
and when fired, the following error is returned:
{
"errorCode": "InvalidTemplate",
"message": "The function 'int' was invoked with a parameter that is not valid. The value cannot be converted to the target type",
"failureType": "UserError",
"target": "If Condition1",
"details": ""
}
Is it possible to convert this returned value to an integer in order to make the comparison? If not, is there a possible work around in order to achieve my desired result?
Looks like the issue is with your dynamic expression. Please correct your dynamic expression similar to below and retry.
If firstRowOnly is set to true : #greater(int(activity('COUNT_RL_WK_GRBY_LOOKUP').output.firstRow.propertyname),20000000)
If firstRowOnly is set to false : #greater(int(activity('COUNT_RL_WK_GRBY_LOOKUP').output.value[zero based index].propertyname),20000000)
The lookup result is returned in the output section of the activity run result.
When firstRowOnly is set to true (default), the output format is as shown in the following code. The lookup result is under a fixed firstRow key. To use the result in subsequent activity, use the pattern of #{activity('MyLookupActivity').output.firstRow.TableName}.
Sample Output JSON code is as follows:
{
"firstRow":
{
"Id": "1",
"TableName" : "Table1"
}
}
When firstRowOnly is set to false, the output format is as shown in the following code. A count field indicates how many records are returned. Detailed values are displayed under a fixed value array. In such a case, the Lookup activity is followed by a Foreach activity. You pass the value array to the ForEach activity items field by using the pattern of #activity('MyLookupActivity').output.value. To access elements in the value array, use the following syntax: #{activity('lookupActivity').output.value[zero based index].propertyname}. An example is #{activity('lookupActivity').output.value[0].tablename}.
Sample Output JSON Code is as follows:
{
"count": "2",
"value": [
{
"Id": "1",
"TableName" : "Table1"
},
{
"Id": "2",
"TableName" : "Table2"
}
]
}
Hope this helps.
Do this - when you run the debugger look at the output from your lookup. It will give a json string including the alias for the result of your query. If it's not firstrow set then you get a table. But for first you'll get output then firstRow and then your alias. So that's what you specify.
For example...if you put alias of your count as Row_Cnt then...
#greater(activity('COUNT_RL_WK_GRBY_LOOKUP').output.firstRow.Row_Cnt,20000000)
You don't need the int function. You were trying to do that (just like I was!) because it was complaining about datatype. That's because you were returning a bunch of json text as the output instead of the value you were after. Totally makes sense after you realize how it works. But it is NOT intuitively obvious because it's coming back with data but its string stuff from json, not the value you're after. And functions like equals are just happy with that. It's not until you try to do something like greater where it looks for numeric value that it chokes.

Firebase observe key contains

I'd like to fetch snapshot which contains typed text. For example node look like this
"Team": {
"Yankees": {
"uid1": "name",
"uid2": "name"
},
"Angels": {
"uid1": "name"
"uid3": "name"
}
and if user typed yan in search bar then I want to fetch "Yankees" snapshot. I saw some document and stack over flow post and tried like so
ref.child("Team").queryStarting(atValue: "yan").queryEnding(atValue: "yan\u{f8ff}").observe
but it doesn't work. How can I do this? Thank you!
Firebase searches are case sensitive. Since your key starts with an uppercase Y, the query only matches if it also does that:
ref.child("Team")
.queryOrderedByKey()
.queryStarting(atValue: "Yan")
.queryEnding(atValue: "Yan\u{f8ff}").observe
I also queryOrderedByKey() to be explicit about what you want to order/filter on.
If you want to allow case-insensitive filtering, the typical approach is to add a property with the all-lowercase value to each team:
"Team": {
"Yankees": {
"teamNameForSearch": "yankees",
"uid1": "name",
"uid2": "name"
},
"Angels": {
"teamNameForSearch": "angels",
"uid1": "name"
"uid3": "name"
}
Now you can search with:
ref.child("Team")
.queryOrdered(byChild: "teamNameForSearch")
.queryStarting(atValue: "yan")
.queryEnding(atValue: "yan\u{f8ff}").observe
A final note is that both approaches only do so-called prefix matches: they find teams whose name starts with what the user typed. If you want a contains operation (as the title of your question suggests), you will have to look beyond Firebase for a solution. For more on that, see Kato's answer here: Firebase query - Find item with child that contains string
You need to change the db to this:
"Team": {
"randomid": {
"team":"Yankees",
"uid1": "name",
"uid2": "name"
},
"randomid": {
"team":"Angels"
"uid1": "name"
"uid3": "name"
}
and now you can do this:
ref.child("Team").queryOrdered(byChild: "team").queryStarting(atValue: "Yan").queryEnding(atValue: "Yan\u{f8ff}").observe
First in your query above, you need to use queryOrdered() to know which child you want to order.
Also in your database the node Team is not equal to anything, it is a parent node that has child nodes.
So to fix this, the node Team needs to be equal to a value(like in the database in this answer) so you will be able to order it and use queryStarting and queryEnding on it.

Is it possible to query by array content?

Using the FIWARE PointOfInterest data model I would like to filter by POI category which is an array. For instance
http://130.206.118.244:1027/v2/entities?type=PointOfInterest&options=keyValues&attrs=name,category&limit=100&q=category=="311"
having as entity instances something like
{
"id": "Museum-f85a8c66d617c23d33847f8110341a29",
"type": "PointOfInterest",
"name": "The Giant Squid Centre",
"category":
[
"311"
]
},
{
"id": "Museum-611f228f42c7fbfa4bd58bad94455055",
"type": "PointOfInterest",
"name": "Museo Extremeño e Iberoamericano de Arte Contemporáneo",
"category":
[
"311"
]
},
Looking to the NGSIv2 specification it seems that works in the way you mention:
Single element, e.g. temperature==40. For an entity to match, it must contain the target property (temperature) and the target property value must be the query value (40) (or include the value, in case the target property value is an array).
I mean, in particular the part that says:
...or include the value, in case the target property value is an array.

MongoDB - Document with different type of value

I'm very new to MongoDB, i tell you sorry for this question but i have a problem to understand how to create a document that can contain a value with different "type:
My document can contain data like this:
// Example ONE
{
"customer" : "aCustomer",
"type": "TYPE_ONE",
"value": "Value here"
}
// Example TWO
{
"customer": "aCustomer",
"type": "TYPE_TWO",
"value": {
"parameter1": "value for parameter one",
"parameter2": "value for parameter two"
}
}
// Example THREE
{
"customer": "aCustomer",
"type": "TYPE_THREE",
"value": {
"anotherParameter": "another value",
{
"someParameter": "value for some parameter",
...
}
}
}
Customer field will be even present, the type can be different (TYPE_ONE, TYPE_TWO and so on), based on the TYPE the value can be a string, an object, an array etc.
Looking this example, i should create three kind of collections (one for type) or the same collection (for example, a collection named "measurements") can contain differend kind of value on the field "value" ?
Trying some insert in my DB instance i dont get any error (i'm able to insert object, string and array on property value), but i would like to know if is the correct way...
I come from RDBMS, i'm a bit confused right now.. thanks a lot for your support.
You can find the answer here https://docs.mongodb.com/drivers/use-cases/product-catalog
MongoDB's dynamic schema means that each need not conform to the same schema.

Is it possible to run a query using Orion where the searching criteria is given by attributes value?

As I create entities in an Orion server, I can search by ID, as flat or using regular expressions:
http://<localhost>:1026/v1/queryContext
Content:
{
"entities": [
{
"type": "Sensor",
"isPattern": "true",
"id": "sensor_1.*"
}
],
"attributes": ["temperature","humidity"]
}
In the above example I'd get all objects of type "Sensor" whose ID starts with "sensor_1", and their attributes "temperature" and "humidity". I wonder if there is any way that would allow me to search by specific attribute value, for example to get those sensors whose humidity is over "60.2", or this selection must be done over the retrieved data queried by ID.
Not in the current Orion version (0.19.0) but it will be possible in the future. Have a look to the attribute::<name> filter with the = operator in this document.