I have a couchdb record structure which looks like this
[
{
"app_version": 2,
"platform": "android",
"session": {
"timestamp": "2014-08-20T00:00:00.000Z",
"session_id": "TOnNIhCNQ31LlkpEPQ7XnN1D",
"ip": "202.150.213.66",
"location": "1.30324,103.5498"
}
},
{
"app_version": 2,
"platform": "android",
"session": {
"timestamp": "2014-08-21T00:00:00.000Z",
"session_id": "TOnNIhCNQ31LlkpEPQ7XnN1D",
"ip": "202.150.213.66",
"location": "1.30324,103.5498"
}
}
{
"app_version": 2,
"platform": "ios",
"session": {
"timestamp": "2014-08-21T00:00:00.000Z",
"session_id": "TOnNIhCNQ31LlkpEPQ7XnN1D",
"ip": "202.150.213.66",
"location": "1.30324,103.5498"
}
},
{
"app_version": 1,
"platform": "ios",
"session": {
"timestamp": "2014-08-21T00:00:00.000Z",
"session_id": "TOnNIhCNQ31LlkpEPQ7XnN1D",
"ip": "202.150.213.66",
"location": "1.30324,103.5498"
}
}
]
I need to query all the records which happened between a a given number of dates and a app_version number, and I want to get the total of each by the platform.
So I wrote a map-reduce function like this;
"total": {
"map": "function(doc) {
date = doc.session.timestamp.split("T")[0];
emit([date, doc.app_version,doc.platform], 1);
}",
"reduce": "_count"
}
This gives me the output properly by grouping the records into dates.
["2014-08-20", 2, "android"] 2
["2014-08-20", 2, "ios"] 1
["2014-08-21", 2, "android"] 1
["2014-08-21", 2, "ios"] 1
But the problem comes when I try to query them using the start_key and end_key (to query by the date range)
Im sending the GET request as follows;
http://localhost/dummy_db_new/_design/views/_view/total?
start_key=["2014-08-20",2,WHAT_TO_PUT_HERE]
&end_key=["2014-08-20",2,WHAT_TO_PUT_HERE]
&group=true
I need to know what to put at the above places for it to have any platform(a string).
Oh I was able to find an answer.
The Answer was to use a wildcard. So basically I sent the request with a wildcard which will accept any platform type
http://localhost/dummy_db_new/_design/views/_view/total?
start_key=["2014-08-20",2,0]
&end_key=["2014-08-20",2,{}]
&group=true
{} means javascript object, so it will accept any JS object.
Related
Current I'm exporting all ARB data by calling API to get all active ARB ids then go through each ARB id to get info stored in each ID. But this process is too long and it makes lots of requests. Is there any way so that I can get all active ARB ids data in one request like that of any database?
https://developer.authorize.net/api/reference/index.html#recurring-billing-get-a-list-of-subscriptions
This function gives only small amount data while I need complete data stored in a profile like this one: https://developer.authorize.net/api/reference/index.html#recurring-billing-get-subscription
But this function only works for single ID.
New Answer
No. The ARBGetSubscriptionListRequest only returns a limited amount of information. If you want detailed information you would need to call ARBGetSubscriptionListRequest and then loop through the results and make an API call for each subscription to get the more granular data.
Due to the potentially large amount of results, you probably should store the results in a database and then have a bunch of scheduled scripts make the subsequent API calls.
Old Answer
Yes. You can call ARBGetSubscriptionListRequest.
Request:
{
"ARBGetSubscriptionListRequest": {
"merchantAuthentication": {
"name": "5KP3u95bQpv",
"transactionKey": "346HZ32z3fP4hTG2"
},
"refId": "123456",
"searchType": "subscriptionActive",
"sorting": {
"orderBy": "id",
"orderDescending": "false"
},
"paging": {
"limit": "1000",
"offset": "1"
}
}
}
Response:
{
"totalNumInResultSet": 1273,
"totalNumInResultSetSpecified": true,
"subscriptionDetails": [
{
"id": 100188,
"name": "subscription",
"status": "canceled",
"createTimeStampUTC": "2004-04-28T23:59:47.33",
"firstName": "Joe",
"lastName": "Tester",
"totalOccurrences": 12,
"pastOccurrences": 6,
"paymentMethod": "creditCard",
"accountNumber": "XXXX5454",
"invoice": "42820041325496571",
"amount": 10,
"currencyCode": "USD"
},
{
"id": 100222,
"name": "",
"status": "canceled",
"createTimeStampUTC": "2004-10-22T21:00:15.503",
"firstName": "asdf",
"lastName": "asdf",
"totalOccurrences": 12,
"pastOccurrences": 0,
"paymentMethod": "creditCard",
"accountNumber": "XXXX1111",
"invoice": "",
"amount": 1,
"currencyCode": "USD"
},
{
"id": 100223,
"name": "",
"status": "canceled",
"createTimeStampUTC": "2004-10-22T21:01:27.69",
"firstName": "asdf",
"lastName": "asdf",
"totalOccurrences": 12,
"pastOccurrences": 1,
"paymentMethod": "eCheck",
"accountNumber": "XXXX3888",
"invoice": "",
"amount": 10,
"currencyCode": "USD"
}
],
"refId": "123456",
"messages": {
"resultCode": "Ok",
"message": [
{
"code": "I00001",
"text": "Successful."
}
]
}
}
I am trying to fetch data from API in react component as
{this.props.buyer && this.props.buyer[0].phone_number[0].number} - it's throwing error
Cannot read property 'number' of undefined
{this.props.buyer && this.props.buyer[0].name} - it's working fine
This is the API data
Orders: {
buyer:
},
}
[
{
"id": 2,
"name": "Qi Xiang",
"type": "Consignee",
"address": {
"id": 2,
"type": "shipping",
"street": "China China",
"city": "Beijing",
"postal_code": "34343",
"province": "23232",
"country": "CN"
},
"email": null,
"phone_number": {
"number": "323232",
"type": "Phone"
},
"id_image_url": "/api/files/24e49645-df42-4984-a
}
]
},
}
Your phonenumber is not array. You must use this:
this.props.buyer[0].phone_number.number
I have a table for some activities like
[
{
"id": 123,
"name": "Ram",
"status": 1,
"activity": "Poster Design"
},
{
"id": 123,
"name": "Ram",
"status": 1,
"activity": "Poster Design"
},
{
"id": 124,
"name": "Leo",
"categories": [
"A",
"B",
"C"
],
"status": 1,
"activity": "Brochure"
},
{
"id": 134,
"name": "Levin",
"categories": [
"A",
"B",
"C"
],
"status": 1,
"activity": "3D Printing"
}
]
I want to get this data from elastic search 5.5 by sorting on field activity, but I need all the data corresponding to name = "Ram" first and then remaining in a single query.
You can use function score query to boost the result based on match for the filter(this case ram in name).
Following query should work for you
POST sort_index/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"boost": "5",
"functions": [{
"filter": {
"match": {
"name": "ram"
}
},
"random_score": {},
"weight": 1000
}],
"score_mode": "max"
}
},
"sort": [{
"activity.keyword": {
"order": "desc"
}
}]
}
I would suggest using a bool query combined with the should clause.
U will also need to use the sort clause on your field.
I would like to serve my visitors the best results possible when they use our search feature.
To achieve this I would like to interpret the search query.
For example a user searches for 'red beds for kids 120cm'
I would like to interpret it as following:
Category-Filter is "beds" AND "children"
Color-filter is red
Size-filter is 120cm
Are there ready to go tools for Elasticsearch?
Will I need NLP in front of Elasticsearch?
Elasticsearch is pretty powerful on its own and is very much capable of returning the most relevant results to full-text search queries, provided that data is indexed and queried adequately.
Under the hood it always performs text analysis for full-text searches (for fields of type text). A text analyzer consists of a character filter, tokenizer and a token filter.
For instance, synonym token filter can replace kids with children in the user query.
Above that search queries on modern websites are often facilitated via category selectors in the UI, which can easily be implemented with querying keyword fields of Elasticsearch.
It might be enough to model your data correctly and tune its indexing to implement the search you need - and if that is not enough, you can always add some extra layer of NLP-like logic on the client side, like #2ps suggested.
Now let me show a toy example of what you can achieve with a synonym token filter and copy_to feature.
Let's define the mapping
Let's pretend that our products are characterized by the following properties: Category, Color, and Size.LengthCM.
The mapping will look something like:
PUT /my_index
{
"mappings": {
"properties": {
"Category": {
"type": "keyword",
"copy_to": "DescriptionAuto"
},
"Color": {
"type": "keyword",
"copy_to": "DescriptionAuto"
},
"Size": {
"properties": {
"LengthCM": {
"type": "integer",
"copy_to": "DescriptionAuto"
}
}
},
"DescriptionAuto": {
"type": "text",
"analyzer": "MySynonymAnalyzer"
}
}
},
"settings": {
"index": {
"analysis": {
"analyzer": {
"MySynonymAnalyzer": {
"tokenizer": "standard",
"filter": [
"MySynonymFilter"
]
}
},
"filter": {
"MySynonymFilter": {
"type": "synonym",
"lenient": true,
"synonyms": [
"kid, kids => children"
]
}
}
}
}
}
}
Notice that we selected type keyword for the fields Category and Color.
Now, what about these copy_to and synonym?
What will copy_to do?
Every time we send an object for indexing into our index, value of the keyword field Category will be copied to a full-text field DescritpionAuto. This is what copy_to does.
What will synonym do?
To enable synonym we need to define a custom analyzer, see MySynonymAnalyzer which we defined under "settings" above.
Roughly, it will replace every token that matches something on the left of => with the token on the right.
How will the documents look like?
Let's insert a few example documents:
POST /my_index/_doc
{
"Category": [
"beds",
"adult"
],
"Color": "red",
"Size": {
"LengthCM": 150
}
}
POST /my_index/_doc
{
"Category": [
"beds",
"children"
],
"Color": "red",
"Size": {
"LengthCM": 120
}
}
POST /my_index/_doc
{
"Category": [
"couches",
"adult",
"family"
],
"Color": "blue",
"Size": {
"LengthCM": 200
}
}
POST /my_index/_doc
{
"Category": [
"couches",
"adult",
"family"
],
"Color": "red",
"Size": {
"LengthCM": 200
}
}
As you can see, DescriptionAuto is not present in the original documents - though due to copy_to we will be able to query it.
Let's see how.
Performing the search!
Now we can try out our index with a simple query_string query:
POST /my_index/_doc/_search
{
"query": {
"query_string": {
"query": "red beds for kids 120cm",
"default_field": "DescriptionAuto"
}
}
}
The results will look something like the following:
"hits": {
...
"max_score": 2.3611186,
"hits": [
{
...
"_score": 2.3611186,
"_source": {
"Category": [
"beds",
"children"
],
"Color": "red",
"Size": {
"LengthCM": 120
}
}
},
{
...
"_score": 1.0998137,
"_source": {
"Category": [
"beds",
"adult"
],
"Color": "red",
"Size": {
"LengthCM": 150
}
}
},
{
...
"_score": 0.34116736,
"_source": {
"Category": [
"couches",
"adult",
"family"
],
"Color": "red",
"Size": {
"LengthCM": 200
}
}
}
]
}
The document with categories beds and children and color red is on top. And its relevance score is twice bigger than of its follow-up!
How can I check how Elasticsearch interpreted the user's query?
It is easy to do via analyze API:
POST /my_index/_analyze
{
"text": "red bed for kids 120cm",
"analyzer": "MySynonymAnalyzer"
}
{
"tokens": [
{
"token": "red",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "bed",
"start_offset": 4,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "for",
"start_offset": 8,
"end_offset": 11,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "children",
"start_offset": 12,
"end_offset": 16,
"type": "SYNONYM",
"position": 3
},
{
"token": "120cm",
"start_offset": 17,
"end_offset": 22,
"type": "<ALPHANUM>",
"position": 4
}
]
}
As you can see, there is no token kids, but there is token children.
On a side note, in this example Elasticsearch wasn't able, though, to parse the size of the bed: token 120cm didn't match to anything, since all sizes are integers, like 120, 150, etc. Another layer of tweaking will be needed to extract 120 from 120cm token.
I hope this gives an idea of what can be achieved with Elasticsearch's built-in text analysis capabilities!
I am new to CouchDB. I have a 9 gb dataset loaded into my couchdb. I am able to map everything correctly. But I cannot reduce any of the results using the code written in the reduce column. When i tried log, log shows that rereduce values as false. Do i need to do anything special while doing the Map() or how to set the rereduce value is TRUE??
A sample of my data is as follows:
{
"_id": "33d4d945613344f13a3ee92933b160bf",
"_rev": "1-0425ca93e3aa939dff46dd51c3ab86f2",
"release": {
"genres": {
"genre": "Electronic"
},
"status": "Accepted",
"videos": {
"video": [
{
"title": "[1995] bola - krak jakomo",
"duration": 349,
"description": "[1995] bola - krak jakomo",
"src": "http://www.youtube.com/watch?v=KrELXoYThpI",
"embed": true
},
{
"title": "Bola - Forcasa 3",
"duration": 325,
"description": "Bola - Forcasa 3",
"src": "http://www.youtube.com/watch?v=Lz9itUo5xtc",
"embed": true
},
{
"title": "Bola (Darrell Fitton) - Metalurg (MV)",
"duration": 439,
"description": "Bola (Darrell Fitton) - Metalurg (MV)",
"src": "http://www.youtube.com/watch?v=_MYpOOMRAeQ",
"embed": true
}
]
},
"labels": {
"label": {
"catno": "SKA005",
"name": "Skam"
}
},
"companies": "",
"styles": {
"style": [
"Downtempo",
"Experimental",
"Ambient"
]
},
"formats": {
"format": {
"text": "",
"name": "Vinyl",
"qty": 1,
"descriptions": {
"description": [
"12\"",
"Limited Edition",
"33 ⅓ RPM"
]
}
}
},
"country": "UK",
"id": 1928,
"released": "1995-00-00",
"artists": {
"artist": {
"id": 390,
"anv": "",
"name": "Bola",
"role": "",
"tracks": "",
"join": ""
}
},
"title": 1,
"master_id": 13562,
"tracklist": {
"track": [
{
"position": "A1",
"duration": "4:33",
"title": "Forcasa 3"
},
{
"position": "A2",
"duration": "5:48",
"title": "Krak Jakomo"
},
{
"position": "B1",
"duration": "7:50",
"title": "Metalurg 2"
},
{
"position": "B2",
"duration": "6:40",
"title": "Balloom"
}
]
},
"data_quality": "Correct",
"extraartists": {
"artist": {
"id": 388200,
"anv": "",
"name": "Paul Solomons",
"role": "Mastered By",
"tracks": "",
"join": ""
}
},
"notes": "Limited to 480 copies.\nA1 is a shorter version than that found on the 'Soup' LP.\nA2 ends in a lock groove."
}
}
My intention is to count the mapped values. My mapping function is as follows:
function(doc){
if(doc.release)
emit(doc.release.title,1)
}
Map results shows around 5800 results
I want to use the following functions in the reduce tab to count:
Reduce:
_count or _sum
It does not give single rounded value. Even i cannot get the simple _count operations right !!! :(
for screenshot,
Please help me !!!
What you got was the sum of values per title. What you wanted, was the sum of values in general.
Change the grouping drop-down list to none.
Check CouchdDB's wiki for more details on grouping.