So we have a People schema and a Project schema, both of which are used on separate pages where you can filter the results. We are at a point where we are realising that we need to filter something like current projects, but on the PEOPLE list. However the data for that lives in Projects, and we are having trouble in finding a clean way to cross-reference the schemas and filter on a computed value.
Eg. Filter the list of people by projects that are currently active (ie. the current time).
There doesn't seem to be any way to do this in ES - my current option is stitching these together in the front-end and doing another "filter" there, but that feels hacky.
Displaying the data on the People list is no issue, it's the filtering.
Has anyone run into this situation before, and how did you resolve it? Appreciate any insight. THanks!
If I understand things correctly, you have two separate indices for people and projects.
Unfortunately, the only way to do things right is to denormalize your data in Elasticsearch and include projects on the people list.
You could also use Parent-child relationships.
Please read this excellent blog posts:
https://rockset.com/blog/can-i-do-sql-style-joins-in-elasticsearch/
and then Parent-Child Modeling in Elasticsearch https://blog.mimacom.com/parent-child-elasticsearch/
The previous link show examples in ElasticSearch 5.6 and 6. I'll provide examples that works in ES 7:
According to the post:
There are four common approaches to managing data in Elasticsearch:
Denormalization, Application-side joins, Nested objects, Parent-child relationships
One-to-one relationships: Object mapping
One-to-many relationships: Nested documents and the parent-child model
Many-to-many relationships: Denormalizing and application-side joins
Challenges with Parent-Child Relationships
Queries are more expensive and memory-intensive because of the join operation. There is an overhead to parent-child constructs, since they are separate documents that must be joined at query time. Need to ensure that the parent and all its children exist on the same shard. Storing documents with parent-child relationships involves implementation complexity.
I'll provide an example ready to execute on ES 7
curl -XDELETE "localhost:9200/project"
curl -XPUT "localhost:9200/project" \
-H 'Content-Type: application/json' \
-d'{
"settings": {
"number_of_shards": 1, "number_of_replicas": 0
},
"mappings": {
"properties": {
"project": { "type": "text" },
"people": { "type": "text" },
"active": { "type": "boolean" },
"project_relations": {
"type": "join",
"relations": {
"project": "people"
}
}
}
}
}'
curl -XPUT "localhost:9200/project/_bulk" \
-H 'Content-Type: application/json' \
-d'
{"index":{"_id":1}}
{"name":"ElasticSearch upgrade","project_relations":{"name":"project"}, "active": true}
{"index":{"_id":2}}
{"name":"Website","project_relations":{"name":"project"}, "active": true}
{"index":{"_id":3}}
{"name":"SQL Server migration","project_relations":{"name":"project"}, "active": false}
'
curl -XPUT "localhost:9200/project/_doc/4?routing=1" \
-H 'Content-Type: application/json' \
-d'
{"people":"Evaldas Buinauskas","project_relations":{"name":"people","parent":1}}
'
curl -XPOST "localhost:9200/project/_doc/5?routing=1" \
-H 'Content-Type: application/json' \
-d'
{"people":"xynon","project_relations":{"name":"people","parent":1}}
'
The routing must correspond to the project id
curl -XPOST "localhost:9200/project/_doc/6?routing=2" \
-H 'Content-Type: application/json' \
-d'
{"people":"Harry scherer","project_relations":{"name":"people","parent":2}}
'
curl -XPOST "localhost:9200/project/_doc/7?routing=2" \
-H 'Content-Type: application/json' \
-d'
{"people":"Darrel Simon","project_relations":{"name":"people","parent":2}}
'
curl -XPOST "localhost:9200/project/_doc/8?routing=3" \
-H 'Content-Type: application/json' \
-d'
{"people":"Juan Carlos Alafita","project_relations":{"name":"people","parent":3}}
'
Search people working on ElasticSearch upgrade and project is active
curl -XGET "localhost:9200/project/_search" \
-H 'Content-Type: application/json' \
-d'
{
"query": {
"has_parent": {
"parent_type": "project",
"query": { "bool": {"must": [ {"match": { "active": true } }, {"match": { "name": "ElasticSearch upgrade" } } ] }}
}
}
}' | jq
Results:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "project",
"_type": "_doc",
"_id": "4",
"_score": 1,
"_routing": "1",
"_source": {
"people": "Evaldas Buinauskas",
"project_relations": {
"name": "people",
"parent": 1
}
}
},
{
"_index": "project",
"_type": "_doc",
"_id": "5",
"_score": 1,
"_routing": "1",
"_source": {
"people": "xynon",
"project_relations": {
"name": "people",
"parent": 1
}
}
}
]
}
}
Search people working on SQL Server migration and project inactive
curl -XGET "localhost:9200/project/_search" \
-H 'Content-Type: application/json' \
-d'
{
"query": {
"has_parent": {
"parent_type": "project",
"query": { "bool": {"must": [ {"match": { "active": false } }, {"match": { "name": "SQL Server migration" } } ] }}
}
}
}
' | jq
curl -XGET "localhost:9200/project/_search" \
-H 'Content-Type: application/json' \
-d'
{
"query": {
"has_parent": {
"parent_type": "project",
"query": { "match_all": {} }
}
}
}'
Related
I'm trying to create a full-text index from the nodejs couchbase library and I can't find the api call, or I'm missing something. It's documented in CURL
Here the FTS Index
{
"name": "myIndex",
"type": "fulltext-index",
"params": {
"mapping": {
"default_mapping": {
"enabled": true,
"dynamic": true
},
"default_type": "_default",
"default_analyzer": "standard",
"default_datetime_parser": "dateTimeOptional",
"default_field": "_all",
"store_dynamic": false,
"index_dynamic": true
},
"store": {
"indexType": "scorch",
"kvStoreName": ""
},
"doc_config": {
"mode": "type_field",
"type_field": "type",
"docid_prefix_delim": "",
"docid_regexp": ""
}
},
"sourceType": "couchbase",
"sourceName": "contacts",
"sourceUUID": "cc9837d1be08c2276d2c123e299a5386",
"sourceParams": {},
"planParams": {
"maxPartitionsPerPIndex": 171,
"numReplicas": 0
},
"uuid": ""
}
You can create your index with the following command:
curl -XPUT -H "Content-type:application/json" http://<USER>:<PASSWORD>#<IP_ADDRESSES>:8094/api/index/NAME_OF_YOUR_INDEX -d #your_json_file.json
One step 6 of this repo there is a real example of how to do it:
https://github.com/deniswsrosa/couchflix
I have simple bot ,I want to set a greating text and add three buttons to it
something like this.
Welcom Johhn to man utd'
-first button
-second button
-third button
here is what I have tried
$ curl -X POST -H "Content-Type: application/json" -d '{
"greeting": [
{
"locale":"default",
"text":"Hello {{user_first_name}}! Welcome to Man utd"
message: {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [{
"title": "Hi , thanks for messaging videommerce",
"buttons": [{
"type": "postback",
"title": "Select video purpose",
"payload": "purpose"
}, {
"type": "postback",
"title": "How to create video",
"payload": "create"
},{
"type": "web_url",
"url": "https://www.videommerce.com/",
"title": "Talk to us directly (moving to Customerly live chat)"
}],
}]
}
}
}
}
]
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=token"
What do I need to change to get what I want?
The greeting webhook does not have the attachment property, as you can see here: documentation.
So, your greeting will work only with the parameters locale and text:
$ curl -X POST -H "Content-Type: application/json" -d '{
"greeting": [
{
"locale":"default",
"text":"Hello {{user_first_name}}! Welcome to Man utd"
}]}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=token"
If you want to show some buttons to the user, the correct way is to call another webhook, after you send the greeting one, the persistent-menu, as described here.. This code will do the work:
curl -X POST -H "Content-Type: application/json" -d '{
"setting_type" : "call_to_actions",
"thread_state" : "existing_thread",
"call_to_actions":[
{
"type":"postback",
"title":"Help",
"payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_HELP"
},
{
"type":"postback",
"title":"Latest Posts",
"payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_LATEST_POSTS"
},
{
"type":"web_url",
"title":"View Website",
"url":"http://yoursite.com/"
}
]
}' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN"
I'm having problems with queries in composer rest server.
I'm building a filter like this:
{
"where": {
"and": [
{
"origin": "web"
},
{
"affiliate": "resource:org.acme.affiliates.Affiliate#2"
},
{
"createdAt": {
"gte": "2018-01-01"
}
},
{
"createdAt": {
"lte": "2018-06-07"
}
}
]
}
}
request:
curl -X GET --header 'Accept: application/json' 'http://localhost:3000/api/User?filter=%7B%22where%22%3A%7B%22and%22%3A%5B%7B%22origin%22%3A%22web%22%7D%2C%7B%22affiliate%22%3A%22resource%3Aorg.acme.affiliates.Affiliate%232%22%7D%2C%7B%22createdAt%22%3A%7B%22gte%22%3A%222018-01-01%22%2C%22lte%22%3A%222018-06-07%22%7D%7D%5D%7D%7D'
response:
[
{
"$class": "org.acme.affiliates.User",
"affiliate": "resource:org.acme.affiliates.Affiliate#2",
"userId": "14",
"email": "diego#duncan.com",
"firstName": "diego",
"lastName": "duncan",
"createdAt": "2018-04-20T20:48:08.151Z",
"origin": "web"
},
{
"$class": "org.acme.affiliates.User",
"affiliate": "resource:org.acme.affiliates.Affiliate#1",
"userId": "15",
"email": "diego#algo.com",
"firstName": "diego",
"lastName": "algo",
"createdAt": "2018-04-20T20:53:40.720Z",
"origin": "web"
}
]
As you see, filters are not working because Affiliate#1 appears.
I tested without createdAt filters and work perfectly, then i tested without affiliate and work good too. I tested with createdAt with range instead gte and lte with the same wrong result.
hlfv1
composer rest server v0.16.6
its a loopback filter issue, most likely to do with the date range comparison. (the other comparisons are fine as you wrote).
The suggestion here -> https://github.com/strongloop/loopback-connector-mongodb/issues/176 would suggest that you need to use the between operator instead for DateTimes. eg
{"where":{"createdAt":{"between": ['2018-01-05 10:00', '2018-05-10 10:00']}}}
I answer my own question:
I was using hlfv1 and composer 0.16.6
After update to hlfv11 and composer 0.19.8 the bug is fixed.
I'm using the github api, trying to find all my commits on a specific day.
This query, as expected, returns all my commits:
https://api.github.com/search/commits?q=committer-email:foo#bar.com
But this query returns that same list, including results outside the specified date range:
https://api.github.com/search/commits?q=committer-email:foo#bar.com&committer-date=2017-08-13..2017-08-14
(These queries require a header to be set: Accept: application/vnd.github.cloak-preview)
Why does the committer-date parameter not work like it's supposed to?
Here are the docs for the commit search: https://developer.github.com/v3/search/#search-commits
There is a small syntax error in the query. Try changing & to + and = to :. Making these changes your query would become -
curl -H 'Accept: application/vnd.github.cloak-preview' \https://api.github.com/search/commits?q=committer-email:foo#bar.com+committer-date:2017-08-13..2017-08-14.
When I run this on my terminal, I just get one commit (see the truncated results below).
Medapas-MacBook-Air:~ medapa$ curl -H 'Accept: application/vnd.github.cloak-preview' \https://api.github.com/search/commits?q=committer-email:foo#bar.com+committer-date:2017-08-13..2017-08-14
{
"total_count": 1,
"incomplete_results": false,
"items": [
{
"url": "https://api.github.com/repos/mstricklin/batis00/commits/af9295b930223e394f7f0d742af351ea3ef02351",
"sha": "af9295b930223e394f7f0d742af351ea3ef02351",
"html_url": "https://github.com/mstricklin/batis00/commit/af9295b930223e394f7f0d742af351ea3ef02351",
"comments_url": "https://api.github.com/repos/mstricklin/batis00/commits/af9295b930223e394f7f0d742af351ea3ef02351/comments",
"commit": {
"url": "https://api.github.com/repos/mstricklin/batis00/git/commits/af9295b930223e394f7f0d742af351ea3ef02351",
"author": {
"date": "2017-08-13T20:10:55.000-05:00",
"name": "mstricklin",
"email": "foo#bar.com"
},
"committer": {
"date": "2017-08-13T20:10:55.000-05:00",
"name": "mstricklin",
"email": "foo#bar.com"
},
"message": "01",
"tree": {
"url": "https://api.github.com/repos/mstricklin/batis00/git/trees/e0fe96439a79eb6d84996f351025488bb0e7114d",
"sha": "e0fe96439a79eb6d84996f351025488bb0e7114d"
},
"comment_count": 0
},
"author": {
"login": "invalid-email-address",
HI I have installed elasticsearch version 0.18.7 and configured couchdb according to these instructions. I am trying to create indexing in the following way:
curl -XPUT '10.50.10.86:9200/_river/tasks/_meta' -d '{
"type": "couchdb",
"couchdb": {
"host": "10.50.10.86",
"port": 5984,
"db": "tasks",
"filter": null
},
"index": {
"index": "tasks",
"type": "tasks",
"bulk_size": "100",
"bulk_timeout": "10ms"
}
}'
and got the message like,
{
"ok": true,
"_index": "_river",
"_type": "tasks",
"_id": "_meta",
"_version": 2
}
when trying to access the url like
curl -GET 'http://10.50.10.86:9200/tasks/tasks?q=*&pretty=true'
then
{
"error": "IndexMissingException[[tasks] missing]",
"status": 404
}
Please guide me how to indexing couchdb using elasticsearch.
I'm not sure where es_test_db2 is coming from. What's the output of this?
curl 10.50.10.86:9200/_river/tasks/_status\?pretty=1