Elastic GET by ID query on rollover alias fails with ""Alias [...] has more than one indices associated with it..." - elasticsearch

Our new rollover indices just rolled over. Now this query...
GET http://my.elastic/system-logs/_doc/7e8017d8-0cb8-4b9e-b021-b2a4b4ac71c7
...fails with this:
"Alias [system-logs] has more than one indices associated with it [[system-logs-000002, system-logs-000001]], can't execute a single index op"
But doing the same thing with _search works fine:
GET http://my.elastic/system-logs/_search/
{
"query": {
"bool": {
"must": [{"term": {"_id": "a1906f52-3957-4f4b-9b40-531422e3a04e"}}]
}
}
}
The exception comes from this code, which looks like there is an allowAliasesToMultipleIndices setting for this, but I haven't been able to find a place to set it.
We're on Elastic 6.8.

In the first http request, you are just trying to find the doc with particular id on an index which in turn is an alias of more than one index.
That's the problem.
Reason:
_doc is a mapping type in elastic search. It is used to segregate documents in the same index. So it cannot check across the indices. It is deprecated. Refer, this also
And you need to use GET request with the permitted queries[like your second example] (term, terms, match, query_string, simple_query_string). Refer

Related

Less restrictive search doesn't return any hits in ElasticSearch

The query below returns hits, for example where name is "Balances by bank":
GET /_search
{ "query": {
"multi_match": { "query": "Balances",
"fields": ["name","descrip","notes"]
}
}
}
So why this doesn't return anything? Note that the query is less restrictive, the word is "Balance" and not "Balances" with an s.
GET /_search
{ "query": {
"multi_match": { "query": "Balance",
"fields": ["name","descrip","notes"]
}
}
}
What search would return both?
You need to change your mapping to be able to do that.
If you didn't specified a mapping with specific analyzers when creating your index, elasticsearch will use the default mapping and analyzer.
The default mapping will map each text field as both text and keyword, so you will be able to performe full text search (match part of the string) and keyword search (match the whole string), but it will use the standard analyzer.
With the standard analyzer your example Balances by bank becomes the following list of tokens: [Balances, by, bank], those items are added to the inverted index and elasticsearch can find the documents when you search for any of them.
When you search for just Balance, this term does not exist in the inverted index and elasticsearch returns nothing.
To be able to return both Balance and Balances you need to change your mapping and use the analyzer for the english language, this analyzer will reduce your terms to their stem and match Balance, Balances as also Balancing, Balanced, Balancer etc.
Look at this part of the documentation to see how the analysis process work.
And of course, you can also search for Balance* and it will return both Balance and Balances, but it is a different query.

How to delete mutiple documents by ID in elasticsearch?

I am trying to delete a short list of documents in one swoop on Elasticsearch 2.4, and I can't seem to give it a query that results in >0 documents getting deleted.
id_list = ["AWeKNmt5qJi-jqXwc6qO", "AWeKT7ULqJi-jqXwc6qS"] #example
# The following does not delete any document (despite these ids being valid)
delres = es.delete_by_query("my_index", doc_type="my_doctype", body={
"query": {
"terms": {
"_id": id_list
}
}
})
If I go one by one, then they get deleted just fine. Which seems to point to my query being the problem.
for the_id in id_list:
es.delete("my_index", doc_type="my_doctype", id=the_id)
I've also tried the ids query instead of terms, but that also does not delete anything.
es.delete_by_query(..., body = {"query": {"ids" { "values": id_list }}})
What am I missing?
delete_by_query was deprecated in ES 1.5.3, removed in ES 2.0, and reintroduced in ES 5.0. From https://www.elastic.co/guide/en/elasticsearch/reference/1.7/docs-delete-by-query.html:
Delete by Query will be removed in 2.0: it is problematic since it silently forces a refresh which can quickly cause OutOfMemoryError during concurrent indexing, and can also cause primary and replica to become inconsistent. Instead, use the scroll/scan API to find all matching ids and then issue a bulk request to delete them.

Elastic search string filter - does such option exists?

I am wondering, is there such an option like string filter?
I've recently bumped into the following error:
RequestError(400, 'search_phase_execution_exception',
'too_many_clauses: maxClauseCount is set to 1024')
According to Lucene's documentation, it says:
Use a filter to replace the part of the query that causes the exception.
Do you have any ideas?
The Lucene FAQ mentions a few approaches to overcoming the TooManyClauses exception which doesn't apply to Elasticsearch as before they used to have terms filter separately but now its part of terms query itself.
so below is the example how you could use terms in the filter context:
{
"query": {
"bool": {
"filter": [
{ "term": { "user" : ["kimchy", "elasticsearch"]},
]
}
}
}
If you really need to use a query instead of a filter then you can update
indices.query.bool.max_clause_count: n in the elasticsearch.yml (replace n with the number of clause count that you need) file of each node of the cluster and restart the cluster.
Note that this will increase the
memory requirements for searches that expand to many terms.

Application-side Joins Elasticsearch

I have two indexes in Elasticsearch, a system index, and a telemetry index. I'd like to perform queries and aggregations on the telemetry index using filters from the systems index. The systems index is relatively small and only receives new documents occasionally, but the telemetry index is much larger and is constantly receiving new documents. This seems like an ideal situation for using an application-side join.
I tried emulating the example query at the pervious link, but it turns out the filtered query is deprecated as of ES 5.0. (Why is this example in the current documentation?!)
Here are my queries:
GET /system/_search
{
"query": {
"match": {
"name": "George's system"
}
}
}
GET /telemetry/_search
{
"query": {
"bool":{
"must": {
"multi_match": {
"operator": "and",
"fields": ["systemId"]
, [1] }
}
}
}
}
}
The second one fails with a json_parse_exception because for some reason it doesn't like the [ ] characters after "fields".
Can anyone provide a simple example of using application-side joins?
Once such a query is defined (perhaps in Kibana's Dev Tools console) is there a way to visualize it in Kibana?
With elastic there is no way to execute two nested queries like in a relational database where the first query uses the response of the second. The example in the application-side join, means that you are actually making two queries (two different requests to elastic) on the application side.
First query you get the list of ids you need to filter on.
Second query you pass the list of ids that you got to the terms filter.
This works when you have no more than 1024 values for systemId. Because terms query has a limit on the number of terms.
Because this query is not feasible, then you can't visualize it in kibana.
In such case you have to sacrifice a little of space and add the systemId to your mapping.
Good Luck!

elastic search: get exact match term results

I have elastic search index with documents having a field "backend_name" like:- google, goolge_staging, google_stg1 etc.
I want only those documents that have "backend_name" = google
I am trying with the term query like this:
{ "query": { "term": { "backend_name": "google" } } }
But it returns me document having "backend_name" as goolge_staging, google_stg1 too. I want just document with "backend_name" = google.
One way to resolve it is to have goolge_staging, google_stg1 etc. in must not list but I want some better way. Suggestions?
It is provably because of the mapping you are using.
Take a look at the Elasticsearch documentation of term query
Try changing the mapping type to keyword so it matches only if it is an exact match.

Resources