Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Elasticsearch Sense contents to demonstrate how transactions with respect to search visibility may be implemented with parent-child relationships using counters. Just copy paste into Sense and run the statements top to bottom.
# Transactions with parent-child relationships using counters.
# Delete the index, just in case it still exists.
DELETE /myindex
# Create the index with a mapping for the actual documents and a mapping for the parent transaction type.
PUT /myindex
{
"mappings": {
"transaction": {
"properties": {
"id": {
"type": "string",
"index": "not_analyzed"
},
"count": {
"type": "integer"
}
}
},
"document": {
"_parent": {
"type": "transaction"
},
"properties": {
"transaction_id": {
"type": "string",
"index": "not_analyzed"
},
"data": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
# Index two documents with transaction 1 as parent, and update the parent document count accordingly. The update os more complex because it is an upsert.
PUT /myindex/document/1?parent=1
{
"transaction_id": "1",
"data": "part1"
}
POST /myindex/transaction/1/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "1",
"count": 1
}
}
PUT /myindex/document/2?parent=1
{
"transaction_id": "1",
"data": "part2"
}
POST /myindex/transaction/1/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "1",
"count": 1
}
}
# Try to search for one of the documents, including a check for the expected count value of the parent document (in this case 3). This will fail because the count of transaction 1 is only 2.
GET /myindex/document/_search
{
"query": {
"filtered": {
"query": {
"match": {
"data": "part1"
}
},
"filter": {
"has_parent": {
"type": "transaction",
"filter": {
"term": {
"count": 3
}
}
}
}
}
}
}
# Index another document of the same transaction.
PUT /myindex/document/3?parent=1
{
"transaction_id": "1",
"data": "part3"
}
POST /myindex/transaction/1/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "1",
"count": 1
}
}
# Again try to search for one of the documents. This will succeed now.
GET /myindex/document/_search
{
"query": {
"filtered": {
"query": {
"match": {
"data": "part1"
}
},
"filter": {
"has_parent": {
"type": "transaction",
"filter": {
"term": {
"count": 3
}
}
}
}
}
}
}
# We can also retrieve all documents belonging to some transaction.
GET /myindex/document/_search
{
"query": {
"filtered": {
"filter": {
"has_parent": {
"type": "transaction",
"filter": {
"bool": {
"must": [
{"term": {"id": "1"}},
{"term": {"count": 3}}
]
}
}
}
}
}
}
}
# Index documents of another transaction.
PUT /myindex/document/10?parent=2
{
"transaction_id": "2",
"data": "part1"
}
POST /myindex/transaction/2/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "2",
"count": 1
}
}
PUT /myindex/document/11?parent=2
{
"transaction_id": "2",
"data": "part2"
}
POST /myindex/transaction/2/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "2",
"count": 1
}
}
# The second transaction is not visible, so searching for all "part1" documents will only show the one for transaction 1.
GET /myindex/document/_search
{
"query": {
"filtered": {
"query": {
"match": {
"data": "part1"
}
},
"filter": {
"has_parent": {
"type": "transaction",
"filter": {
"term": {
"count": 3
}
}
}
}
}
}
}
# The second transaction completes.
PUT /myindex/document/12?parent=2
{
"transaction_id": "2",
"data": "part3"
}
POST /myindex/transaction/2/_update
{
"script": "ctx._source.count += 1",
"upsert": {
"id": "2",
"count": 1
}
}
# Sarch will show us the "part1" documents of all completed transactions.
GET /myindex/document/_search
{
"query": {
"filtered": {
"query": {
"match": {
"data": "part1"
}
},
"filter": {
"has_parent": {
"type": "transaction",
"filter": {
"term": {
"count": 3
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment