Missing rollover_alias index setting in OpenSearch - opensearch

I am trying to setup index rollover in OpenSearch with simple min_doc_count condition, but I am getting "message": "Missing rollover_alias index setting [index=app_logs-000002]" error.
I have a rollover alias called app_logs, and also have the following policy (for demo purpose it is dummy to rollover after 3 documents) attached to indexes:
PUT _plugins/_ism/policies/rollover_policy
{
"policy": {
"description": "Rollover policy",
"default_state": "rollover",
"states": [
{
"name": "rollover",
"actions": [
{
"rollover": {
"min_doc_count": 3
}
}
],
"transitions": []
}
],
"ism_template": [
{
"index_patterns": [
"app_logs-*"
]
}
]
}
}
GET _cat/aliases:
app_logs app_logs-000001 - - - false
app_logs app_logs-000002 - - - true
GET _cat/indices:
yellow open app_logs-000002 V4j0gxaYTcqoQZvtd0u2zc 1 1 6 0 4.1kb 4.1kb
yellow open app_logs-000001 AnPjlOq6Q5We411z2q_YpQ 1 1 5 0 18.8kb 18.8kb
...
When doing
GET _opendistro/_ism/explain/app_logs-000002?pretty I get:
{
"app_logs-000002" : {
"index.plugins.index_state_management.policy_id" : "rollover_policy",
"index.opendistro.index_state_management.policy_id" : "rollover_policy",
"index" : "app_logs-000002",
"index_uuid" : "V4j0gxaYTcqoQZvtd0u2zc",
"policy_id" : "rollover_policy",
"policy_seq_no" : -2,
"policy_primary_term" : 0,
"rolled_over" : false,
"index_creation_date" : 1659299029428,
"state" : {
"name" : "rollover",
"start_time" : 1659299410303
},
"action" : {
"name" : "rollover",
"start_time" : 1659424192817,
"index" : 0,
"failed" : true,
"consumed_retries" : 3,
"last_retry_time" : 1659424804833
},
"step" : {
"name" : "attempt_rollover",
"start_time" : 1659424192817,
"step_status" : "failed"
},
"retry_info" : {
"failed" : false,
"consumed_retries" : 0
},
"info" : {
"message" : "Missing rollover_alias index setting [index=app_logs-000002]"
},
"enabled" : false
},
"total_managed_indices" : 1
}
When I do GET app_logs-000002/_settings I get:
{
"app_logs-000002" : {
"settings" : {
"index" : {
"creation_date" : "1659299029428",
"number_of_shards" : "1",
"number_of_replicas" : "1",
"uuid" : "V4j0gxaYTcqoQZvtd0u2zc",
"version" : {
"created" : "136227827"
},
"provided_name" : "app_logs-000002"
}
}
}
}
so yes rollover alias setting is really missing there. But I would expect that this will be added automatically.
When I do GET _template I get:
{
"ism_rollover" : {
"order" : 0,
"index_patterns" : [
"app_logs-*"
],
"settings" : {
"index" : {
"opendistro" : {
"index_state_management" : {
"rollover_alias" : "app_logs"
}
}
}
},
"mappings" : { },
"aliases" : { }
}
}
so rollover_alias is there in template. Why this is not used in a new index from template?
Thanks!

I experienced a similar problem. The issue was that the indices needed to be created after the ism policy and template. I'm not sure if you managed to find a solution but perhaps for those future users this could prove useful.
Some docs:
Very useful sample on setting up a rolling index strategy: https://opensearch.org/docs/latest/im-plugin/ism/policies/#sample-policy-with-ism-template-for-auto-rollover
Official AWS docs on the same topic with some examples: https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ism.html.
A great writeup on common errors experienced when implementing a rolling index ISM policy: https://aws.amazon.com/premiumsupport/knowledge-center/opensearch-failed-rollover-index/
In your case it appears that the policy was not correctly applying to your indices which is likely a result of you creating your indices before the policy and template were created. If you want to add a policy to an index see the step 6 of Create an ISM policy in the linked AWS docs above:
POST _plugins/_ism/add/my-index
{
"policy_id": "my-policy-id"
}
Here is how I went about solving this problem using a policy and template:
Implement an ISM policy (as you did above)
Create an ISM template
PUT _template/ism_rollover_app
{
"index_patterns": "app_logs-*",
"settings": {
"index": {
"opendistro.index_state_management.rollover_alias": "app_logs"
}
}
}
Create an initial index called app_logs-00001 (or some variant that matches the regex ^.*-\d+$)
This should hopefully see app_logs-00001 be created from the ism_rollover_app template and have the app_logs index associated with it. This should subsequently fix this missing alias issue.

Related

How to get the total number of times each object has been referenced in a collection?

So what i am trying to find is how many time each kite was flown by each person, the db looks like this:
{
"_id" : ObjectId("5bccf4d7ac8fa95f43a964c2"),
"KITE" : {
"registration" : "DTH498"
}
}
{
"_id" : ObjectId("5bccf4d7ac8fa95f43a964c3"),
"KITE" : {
"registration" : "HKJ607"
}
}
{
"_id" : ObjectId("5bccf4d7ac8fa95f43a964c4"),
"KITE" : {
"registration" : "GCF21"
}
}
{
"_id" : ObjectId("5bccf4d7ac8fa95f43a964cf"),
"PERSON" : {
"name" : "H.Y",
"used" : [
{
"registration" : "DTH498"
},
{
"registration" : "HKJ607"
},
{
"registration" : "GCF21"
}
]
}
}
{
"_id" : ObjectId("5bccf4d7ac8fa95f43a9leo5"),
"PERSON" : {
"name" : "T.G",
"used" : [
{
"registration" : "DTH498"
},
{
"registration" : "HKJ607"
},
{
"registration" : "GCF21"
}
]
}
}
{
"_id" : ObjectId("5bccf4d7ac8fro4943a01pak"),
"PERSON" : {
"name" : "X.L",
"used" : [
{
"registration" : "DTH498"
},
{
"registration" : "HKJ607"
},
{
"registration" : "GCF21"
}
]
}
}
Right now i can only use the aggregation framework, with that said i've managed to list all kites that have been used:
db.data.aggregate([
{"$unwind":"$PERSON.used"},
{"$group":{"_id":"$PERSON.used.registration"}}
]).pretty();
The result i'm trying to get to would have the registration of the kite and the number of times it has been used overall.
I'm not sure how it would look but, what im thinking is:
1. Somehow get all used array objects registrations into a new array so it one big list of all the times each kite has been used
2. Group the array by registration and use sum to display how many duplicates each group had.
I DID IT, WOOOO!
so if anyone ever stumbles upon my question, heres the answer.
First unwind the used array
Second project only the registrations
Third group with an _id of registration and count with $sum
db.data.aggregate([
{"$unwind":"$PERSON.used"},
{"$project":{"registration":"$PERSON.used.registration","_id":0}},
{"$group":{"_id":"$registration", "count":{"$sum":1}}}
]);

Mongodb update and delete operations in a single query

I have documents in which I would like to update the hostUser with one of the members of the document,also have to delete the record from the member document and add the chips of the deleted member in the club chips.
Here is the sample document.
{
"_id" : "1002",
"hostUser" : "1111111111",
"clubChips" : 10000,
"requests" : {},
"profile" : {
"clubname" : "AAAAA",
"image" : "0"
},
"tables" : [
"SJCA3S0Wm"
],
"isDeleted" : false,
"members" : {
"1111111111" : {
"chips" : 0,
"id" : "1111111111"
},
"2222222222" : {
"chips" : 0,
"id" : "2222222222"
}
}
}
This is what I have tried.
db.getCollection('test').updateMany({"hostUser":"1111111111"},
{"$set":{"hostUser":"2222222222"},"$unset":{"members.1111111111":""}})
This is how you would handle unset and set in a single call to updateMany. Can you please clarify what you meant by "check if the values exist in the member field"?
db.getCollection('test').updateMany(
{"hostUser":"1111111111"},
{
'$set': {"hostUser":"2222222222"} ,
'$unset': {"members.1111111111":""}
}
)

Elasticsearch doesn't find value in range query

I launch following query:
GET archive-bp/_search
{
"query": {
"bool" : {
"filter" : [ {
"bool" : {
"should" : [ {
"terms" : {
"naDataOwnerCode" : [ "ACME-FinServ", "ACME-FinServ CA", "ACME-FinServ NY", "ACME-FinServ TX", "ACME-Shipping APA", "ACME-Shipping Eur", "ACME-Shipping LATAM", "ACME-Shipping ME", "ACME-TelCo-CN", "ACME-TelCo-ESAT", "ACME-TelCo-NL", "ACME-TelCo-PL", "ACME-TelCo-RO", "ACME-TelCo-SA", "ACME-TelCo-Treasury", "Default" ]
}
},
{
"bool" : {
"must_not" : {
"exists" : {
"field" : "naDataOwnerCode"
}
}
}
} ]
}
}, {
"range" : {
"bankCommunicationStatusDate" : {
"from" : "2006-02-27T06:45:47.000Z",
"to" : null,
"time_zone" : "+02:00",
"include_lower" : true,
"include_upper" : true
}
}
} ]
}
}
}
And I receive no results, but the field exists in my index.
When I strip off the data owner part, I still have no results. When I strip off the bankCommunicationDate, I get 10 results, so there is the problem.
The query of only the bankCommunicationDate:
GET archive-bp/_search
{
"query" :
{
"range" : {
"bankCommunicationStatusDate" : {
"from" : "2016-04-27T09:45:43.000Z",
"to" : "2026-04-27T09:45:43.000Z",
"time_zone" : "+02:00",
"include_lower" : true,
"include_upper" : true
}
}
}
}
The mapping of my index contains the following bankCommunicationStatusDate field:
"bankCommunicationStatusDate": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
}
And there are values for the field bankCommunicationStatusDate in elasticsearch:
"bankCommunicationStatusDate": "2016-04-27T09:45:43.000Z"
"bankCommunicationStatusDate": "2016-04-27T09:45:47.000Z"
What is wrong?
What version of Elastic Search do you use?
I guess the reason is that you should use "gte/lte" instead of "from/to/include_lower/include_upper".
According to documentation to version 0.90.4
https://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-range-query.html
Deprecated in 0.90.4.
The from, to, include_lower and include_upper parameters have been deprecated in favour of gt,gte,lt,lte.
The strange thing is that I have tried your example on elastic search version 1.7 and it returns data!
I guess real depreciation took place much later - between 1.7 and maybe newer version you have.
BTW. You can isolate the problem even further using Sense plugin for Chrome and this code:
DELETE /test
PUT /test
{
"mappings": {
"myData" : {
"properties": {
"bankCommunicationStatusDate": {
"type": "date"
}
}
}
}
}
PUT test/myData/1
{
"bankCommunicationStatusDate":"2016-04-27T09:45:43.000Z"
}
PUT test/myData/2
{
"bankCommunicationStatusDate":"2016-04-27T09:45:47.000Z"
}
GET test/_search
{
"query" :
{
"range" : {
"bankCommunicationStatusDate" : {
"gte" : "2016-04-27T09:45:43.000Z",
"lte" : "2026-04-27T09:45:43.000Z"
}
}
}
}

How to add resource and specify related element?

I have a simple API for a game tip website:
/class is the endpoint for in game classes
/tip is the endpoints for the tips
/user is the endpoint for the users
Each tip has 3 relations:
(:User)-[:AUTHORED]-(:Tip)
(:Class)<-[:FOR]-(:Tip)
(:Class)<-[:AGAINST]-(:Tip)
When I create a Tip using POST, I do'nt know how to add relations at the create time.
I can do this way: Add relation to another node in SDN4 + REST after creating the resource, but I want to do it with only one query.
EDIT:
I tried to POST this:
'{"content":"TEST", "forClass":"/class/2", "againstClass":"/class/2"}'
and the item has been created, no InvalidArgument Exception raised, but if I go to my class resource's tips, I don't have any tips:
GET /class/2/tips:
{
"_embedded" : {
"tip" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/class/2/tips"
}
}
}
GET /tip/9 (the created one):
{
"content" : "TEST",
"_links" : {
"self" : {
"href" : "http://localhost:8080/tip/9"
},
"tip" : {
"href" : "http://localhost:8080/tip/9"
},
"author" : {
"href" : "http://localhost:8080/tip/9/author"
},
"againstClass" : {
"href" : "http://localhost:8080/tip/9/againstClass"
},
"forClass" : {
"href" : "http://localhost:8080/tip/9/forClass"
}
}
}
GET /tip/9/forClass:
{
"name" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/class/2"
},
"bnSClass" : {
"href" : "http://localhost:8080/class/2"
},
"tips" : {
"href" : "http://localhost:8080/class/2/tips"
}
}
}

Need help to search document with random field names

I looked through the MongoDB documentation and googled this question but couldn't really find a suitable answer.
encounter a problem where I need to search documents in a collection, but 3 fields name will change from one doc to another even though they are always at the same positions.
In the following example, the 366_DAYS can be 2_HOURS, 35_DAYs etc from document to document, but they will be in the same position.
The _XC4ucB8sEeSybaax341rBg will change to another random string from doc to doc, again it will be at the same position for all docs.
Other fields do not change name and stay at the same position.
I want a query to search for records where debitAmount >=creditAmount or endDate > now().
set02:PRIMARY> db.account.find({ _id: "53e51b1b0cf22cb159fa5f38" }).pretty()
{
"_id" : "53e51b1b0cf22cb159fa5f38",
"_version" : 6,
"_transId" : "e3e96377-a2d2-4b75-a946-f621df182c5e-2719",
"accountBalances" : {
"TEST_TIME" : {
"thresholds" : {
},
"deprovisioned" : false,
"quotas" : {
"366_DAYS" : {
"thresholds" : {
},
"quotaCode" : "366_DAYS",
"credits" : {
"_XC4ucB8sEeSybaax341rBg" : {
"startDate" : ISODate("2014-08-08T18:46:51.351Z"),
"creditAmount" : "86460",
"endDate" : ISODate("2014-08-09T18:48:19Z"),
"started" : true,
"debits" : {
"consolidated" : {
"creationDate" : ISODate("2014-08-08T19:15:55.396Z"),
"debitAmount" : "1300",
"debitId" : "consolidated"
}
},
"creditId" : "_XC4ucB8sEeSybaax341rBg"
}
}
}
},
"expiredReservations" : {
},
"accountBalanceCode" : "TEST_TIME",
"reservations" : {
}
}
},
"subscriberId" : "53e51b1b0cf22cb159fa5f38"
}
Can you use arrays for quotas and credits? That would make the path be the same.
"quotas": [
{
"days": 365,
"thresholds": {},
"credits": [
{
"id": "_XC4ucB8sEeSybaax341rBg"
}
]
}
]
Two cases come to mind. Which one applies to you is unclear to me from the question so providing for both possibilities.
CASE 1:
You will always have either 366_DAYS, 2_HOURS or 35_DAYS inside quotas and only one possible creditId per document. If this is the case, then why replicate the quotaCode and the creditId both as a sub-field and as the key inside quotas and credits respectively. You could alter the structure of your document as follows:
{
"_id": "53e51b1b0cf22cb159fa5f38",
"_version": 6,
"_transId": "e3e96377-a2d2-4b75-a946-f621df182c5e-2719",
"accountBalances": {
"TEST_TIME": {
"thresholds": {},
"deprovisioned": false,
"quotas": {
"thresholds": {
},
"quotaCode": "366_DAYS",
"credits": {
"startDate": ISODate("2014-08-08T18:46:51.351Z"),
"creditAmount": "86460",
"endDate": ISODate("2014-08-09T18:48:19Z"),
"started": true,
"debits": {
"consolidated": {
"creationDate": ISODate("2014-08-08T19:15:55.396Z"),
"debitAmount": "1300",
"debitId": "consolidated"
}
},
"creditId": "_XC4ucB8sEeSybaax341rBg"
}
},
"expiredReservations": {
},
"accountBalanceCode": "TEST_TIME",
"reservations": {
}
}
},
"subscriberId": "53e51b1b0cf22cb159fa5f38"
}
Now the fieldPath for fields in your queries would be:
"accountBalances.TEST_TIME.quotas.credits.creditAmount"
"accountBalances.TEST_TIME.quotas.credits.debits.consolidated.debitAmount"
"accountBalances.TEST_TIME.quotas.credits.startDate"
CASE 2:
quotas and credits may contain more than one subdocument. In this case viktortnk's approach of having quotas and credits as arrays will work. The fieldPath for your queries may then be written as:
"accountBalances.TEST_TIME.quotas.[zero-base-index].credits.[zero-base-index].creditAmount"
"accountBalances.TEST_TIME.quotas.[zero-base-index].credits.[zero-base-index].debits.consolidated.debitAmount"
"accountBalances.TEST_TIME.quotas.[zero-base-index].credits.[zero-base-index].startDate"