Is there any solution to do the "NOT IN" functionality in Elasticsearch? - mysql

Here is a simple but difficult question.
I want to do an aggregation for a query results that should be use "NOT IN" functionality like any RDBMS' SQL.
For example, I want to do a job something like below.
curl -XGET http://localhost:9200/my_index/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
!!! Documents whose 'user_id' field value is 'NOT IN' distinct user_ids where the 'action' field value is 'signup' !!!
}
}
},
"aggregations": {
"distinct_users":{
"cardinality": {
"field": "user_id",
"precision_threshold": 1000000
}
}
}
}'
Edit
Here is an example data.
curl -s -XPOST 'localhost:9200/my_index/my_type/1' -d'{ "user_id": 1234, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/2' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/3' -d'{ "user_id": 1234, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/4' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/5' -d'{ "user_id": 5678, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/6' -d'{ "user_id": 9012, "action": "signup" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/7' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/8' -d'{ "user_id": 9012, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/9' -d'{ "user_id": 3456, "action": "visit" }'
curl -s -XPOST 'localhost:9200/my_index/my_type/10' -d'{ "user_id": 3456, "action": "visit" }'
What I really want to get is the "Documents whose user_id DOES NOT signed up based on these log data".
So, documents [4, 5, 9, 10] are the final results what I want to get.
Is it possible to get the results what I want in Elasticsearch?
Thanks in advance.

No, elasticsearch does not do joins and what you are asking for is a variation of a join.
As pointed out above, it does have parent child relations and nested objects though which might help you somewhat, depending on your domain.
Elasticsearch also does not have a distinct feature which you need as well. But you can sort of fake it with a terms aggregation.
However, that does not help you here since you really need a join for this. So, the only solution here is to do the join outside of elasticsearch. Depending on your data size, that might be expensive. Also see application side joins.

if you use the not filter Elasticsearch will check each document in turn - the following will return all documents that have an action where action is anything but signup.
curl -XGET http://localhost:9200/myindex/my_type/_search?pretty -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"term" : { "action" : "signup" }
}
}
}
}
}'
To meet the requirement where a userid is returned if it doesn't have any instances of action=signup then you'll need to set up a parent child relationship.
in this case, Userid would be unique across all user type documents. Each user document would have one or more action type children.
The following query checks the action child and returns the user document.
curl -XGET 'http://localhost:9200/myindex/my_type/_search?pretty' -d '{
"query": {
"filtered": {
"filter": {
"not" : {
"has_child": { "type": "my_action", "term" : { "action" : "signup" }}
}
}
}
}
}'

Related

Filter parameters from json request

i try to put a bash script who'll get only the data value from the next request :
curl -H "X-Vault-Token: $VAULT_TOKEN" \
-X GET http://127.0.0.1:8200/v1/secret/data/hello
but when i want to do | filter after :
curl -H "X-Vault-Token: $VAULT_TOKEN" \
-X GET http://127.0.0.1:8200/v1/secret/data/hello | filter
It doesn't work.
I tried to switch to grep instead, but it didn't do what I expected.
I have the answer from my request :
{
"request_id": "c1b3e19b-9f6b-a2af-1a1e-69b42bd9c81e",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"data": {
"foo": "world"
},
"metadata": {
"created_time": "2021-04-25T13:08:13.778097752Z",
"deletion_time": "",
"destroyed": false,
"version": 1
}
},
"wrap_info": null,
"warnings": null,
"auth": null
}
And i only want the field data, is anyone have encountered this ?

Cocatenate 2 variables to put inside json is not working

I need to concatenate 2 variables, but when i execute the bash code i get this error filters.api.malformed_request_body.
I need to get the current IPs, to be able to add a new IP to the filter, that's because i need to use two variables, $a is the current IP that is in my firewall rule, and $b is the new IP that i will add.
From Cloudflare
To preserve existing values, issue a GET request and based on the response, determine which fields (and respective values) to include in your PUT request and that way, avoid any undesired overwrites.
Code:
a=122.16.89.10
b=137.77.77.77
curl -X PUT \
-H "X-Auth-Email: EMAIL" \
-H "X-Auth-Key: KEY" \
-H "Content-Type: application/json" \
-d '[
{
"id": "ID",
"paused": false,
"expression": "(ip.src in {'$a'" "'$b'})",
"description": "Block IP"
}
]' "https://api.cloudflare.com/client/v4/zones/ZONE/filters"
I also tried: "(ip.src in {'$a $b'})" and:
new_filter="$a $b"
...
...
"(ip.src in {'$new_filter'})"
If i echo $new_filter it shows the correct result:
new_filter="$a $b"
echo $new_filter
#122.16.89.10 137.77.77.77
When i use the variable $new_filter it also show this error curl: (3) [globbing] unmatched close brace/bracket in column 13 line 13 is this one -H "Content-Type: application/json" \.
None worked, why? I get this error:
{
"result": null,
"success": false,
"errors": [
{
"code": 10014,
"message": "filters.api.malformed_request_body"
}
],
"messages": []
}
This works: "(ip.src in {'$a'})".
Well, let's take your first example and modify it to print the JSON body:
export a=122.16.89.10
export b=137.77.77.77
echo '[
{
"id": "ID",
"paused": false,
"expression": "(ip.src in {'$a'" "'$b'})",
"description": "Block IP"
}
]'
The output is this:
{
"id": "ID",
"paused": false,
"expression": "(ip.src in {122.16.89.10" "137.77.77.77})",
"description": "Block IP"
}
]
You can see that JSON is not valid. The double quotes are unbalanced in expression.
Try "expression": "(ip.src in {'$a' '$b'})", instead -- that will produce valid JSON.

Uploading linked Revit models to Autodesk Forge

I've been trying to use the Post references (https://developer.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-references-POST/) to set up the reference between two files in forge but although I get a message "success" as result when I try it on the forge viewer I still see the files separately even after I translate the models. Has someone been through the same issue?
Without seeing you code it is hard to tell what is happening. Below I copied my bash script code which references/translate an obj with material and texture.
Au.obj
+- Au.mtl
+- Au.jpg
After upload, I got these
idObj="urn:adsk.objects:os.object:cyrillejcrja/Au.obj"
idMtl="urn:adsk.objects:os.object:cyrillejcrja/Au.mtl"
idJpg="urn:adsk.objects:os.object:cyrillejcrja/Au.jpg"
the code to set references, now
urn=$(xbase64encode $idObj)
job='{
"urn": "'${idObj}'",
"filename": "Au.obj",
"references": [{
"urn": "'${idMtl}'",
"relativePath": "./Au.mtl",
"filename": "Au.mtl",
"references": [{
"urn": "'${idJpg}'",
"relativePath": "./Au.jpg"
}]
}]
}'
response=$(curl -H "Content-Type: application/json" \
-H "Authorization: ${bearer}" \
-X POST ${ForgeHost}/modelderivative/v2/designdata/${urn}/references \
-k -s -d "${job}")
Here is got a reply like below which only means that the references are registered.
{
"result": "success"
}
Now, I do this to translate the obj and use the references
urn=$(xbase64encode $idObj)
job='{
"input": {
"urn": "'${urn}'",
"checkReferences": true
},
"output": {
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}'
response=$(curl -H "Content-Type: application/json" \
-H "Authorization: ${bearer}" \
-H "x-ads-force: true" \
-X POST ${ForgeHost}/modelderivative/v2/designdata/job \
-k -s -d "${job}")
Note the "checkReferences": true, as documented here.
Now, I can wait the translation to complete and see the result in the Viewer.
For reference the xbase64safeencode function used above
function xbase64safeencode () { local id64=$(echo -ne $1 | base64 $wrap_arg | tr -d '=' | tr '+/' '-_'); echo $id64; }
#Cyrille, this is my request:
curl -X 'POST' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsI' -H 'Content-Type: application/json' -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/{urn}/references' -d
'{
"urn": "urn:adsk.objects:os.object:bucket/non-existent.rvt",
"filename": "",
"references": [
{
"urn": "urn:adsk.objects:os.object:bucket/non-existent.rvt",
"relativePath": "",
"filename": ""
}
]
}'
I got as result:
'{
"result": "success"
}'
The point is I'm getting success as a result even when I do not have the specified file on the server, so I'd suggest few server-side validations, for example, when a model has been translated once we can't set as reference right so it should at least return an error. Thank you and I hope this helps.

Importing json into couchdb such that each object becomes a document

I have a JSON file in the following format:
"rows": [
{
"key": [
null,
null,
"dco_test_group",
"3d3ce6270fdfuashge12e1d41af93179",
"test_djougou"
],
"value": {
"lat": "31.538208354844658",
"long": "91.98762580927113"
}
},
{
"key": [
null,
null,
"dco_test_group",
"4cda7jhsadgfs6123hsdaa9069ade2",
"test_ouake"
],
"value": {
"lat": "59.696798503352547",
"long": "11.6626995307082464"
}
},
I want to import the file such that each object inside rows becomes a couchdb document. Right now, I have the following code:
curl -X PUT --data-binary #"C:\Users\me\Dropbox (Personal)\Research\Folder\location.json" http://127.0.0.1:5984/db/document_name
This adds all the data inside document_name.
If I try:
curl -X PUT --data-binary #"C:\Users\me\Dropbox (Personal)\Research\Folder\location.json" http://127.0.0.1:5984/db
a new db is created but no data gets added. How do I edit the code to get the desired output?
UPDATE 1
Does it matter if all the data is in record? Are there any rules analogous to 5 normal forms of RDB?
Use the bulk-document-api for this. Here is an example from the docs >> https://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Modify_Multiple_Documents_With_a_Single_Request
$ DB="http://127.0.0.1:5984/mydb"
$ curl -H "Content-type:application/json" -d '{"docs":[{"key":"baz","name":"bazzel"},{"key":"bar","name":"barry"}]}' -X POST $DB/_bulk_docs
$ curl -H "Content-type:application/json" -d #your_file.json -X POST $DB/_bulk_docs
Note, that all docs are items within a 'docs' array.

cURL Response JSON RestAPI

I need to delete some wrong data, inserted in a lot of processes, and I need to figure if this is possible with cURL and rest API, with a script in sh, batch or something like this:
curl -u admin:admin -i -H "Accept: application/json" -X GET "http://json_bpm.com/wle/v1/service/6112449?action=getData&fields=context"
First I just need the result map.
Output:
{"status":"200","data":{"result":"{\"context\":{\"name\":\"xxx\" (...)
"resultMap":{"context":{"name\":"xxx\" (...) }}}
Because I need to remove the userDelete array (see below) for thousands of processes, and set this again using curl. If you know how to remove arrays from JSON too, you're the man. :)
{
"context": {
"name": "Change Process",
"startUser": {
"user": "0001"
},
"endUser": {
"user": "0001"
},
"userDelete": {
"user": "0002"
},
"origin": "GUI",
"userAction": "Change Process"
}
}