Elastic search returning no results - elasticsearch

I have Elasticsearch demonstrating counterintuitive behaviour. This is reproducible with the following steps
1) Add a document
curl -XPUT 'http://myelasticseach:1234/anindex/atype/1' -d '
{
obj1:
{
foo : "bar"
},
obj2 :
{
baz : "qux"
}
}'
2) Search for 'bar'. I expect and get 1 result
curl -XGET 'http://myelasticseach:1234/anindex/_search?q=bar'
3) Search for 'qux'. I expect and get 1 result
curl -XGET 'http://myelasticseach:1234/anindex/_search?q=qux'
4) Update document
curl -XPUT 'http://myelasticseach:1234/anindex/atype/1' -d '
{
atype:
{
foo : "bar"
},
obj2 :
{
baz : "qux"
}
}'
5) Search for 'bar'. I expect and get 1 result
curl -XGET 'http://myelasticseach:1234/anindex/_search?q=bar'
6) Sarch for 'qux'. I expect 1 result, but get 0???
curl -XGET 'http://myelasticseach:1234/anindex/_search?q=qux'
Why when the nested object in the document has a key matching the type of the document can I no longer get results from the rest of the objects with keys that do not match the type.

This is a known issue in elasticsearch 0.90.0.
See 'Wrong mapping using a nested object with same name as its type'
https://github.com/elasticsearch/elasticsearch/issues/3005

Related

Elasticsearch Document search related

I have an Index in Elasticsearch with one document we can say doc id 01 and I updated the document with new doc ID we can say id 02 now I have two documents.
My Question is I want only one latest document(which is doc id 02) in search query(index/_search)
what will be the query for such type of scenario.
If you want to get the document having the maximum value (assuming you are creating doc_id in increase numerical order from the example given) for doc_id, you can use this query:
curl "https://{es_endpoint}/sample_index/_search?pretty" -H 'Content-Type: application/json' -d'
{
"sort" : [
{ "_id" : {"order" : "desc"}}
],
"size": 1
}'

Elasticsearch: How to achieve a case sensitive term query?

I try to query for items by a field called unit which is case sensitive (like kWh), but my term query matches only when I query for kwh (lower case W). What I have seen in the docs is that term should be the right one for case sensitivity, so I am not sure what I am doing wrong.
## Create an item
curl -X POST "localhost:9200/my_index/my_type/my_id" -H 'Content-Type: application/json' -d'{"point_name" : "my_point_name", "unit" : "kWh"}'
=> {"_index":"my_index","_type":"my_type","_id":"my_id","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"created":true}
## Try to query it by unit with exact match (kWh)
curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'{"query" : { "bool" : {"must" : [{ "term" : {"unit" : "kWh"}}]}}}'
=> {"took":36,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
## Query with lower case unit kwh
curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'{"query" : { "bool" : {"must" : [{ "term" : {"unit" : "kwh"}}]}}}'
=> {"took":12,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"my_index","_type":"my_type","_id":"my_id","_score":0.2876821,"_source":{"point_name" : "my_point_name", "unit" : "kWh"}}]}}
I don't want to use match here since I create these queries by other fields as well and I want to ensure an exact match behaviour. Can anyone point me how the query would be correct and why this term query does not work?
I am using this dockerimage as my server:
docker.elastic.co/elasticsearch/elasticsearch:6.2.4

Using a string to build Query DSL for Elasticsearch

I'm using Meteor (so Javascript, Node, NPM, etc) and would like to provide a simple text input for users to search via Elasticsearch. I would like to be able to use modifiers on the text like + and "" and search for a specific field. I'm looking for something that can convert a plain text input into Elasticsearch Query DSL.
These would be some example queries:
This query would mean that the keyword "tatooine" must exist:
stormtrooper +tatooine
This would mean that "death star" should be one keyword:
stormtrooper "death star"
This would search for the keyword "bloopers" only in the category field:
stormtrooper category=bloopers
Is there a library that can do this? Can a generic solution exist or is this why I can't find any existing answers to this?
simple_query_string would support your query syntax out of the box, except for category=bloopers which should be category:bloopers instead, but otherwise it should work:
curl -XPOST localhost:9200/your_index/_search -d '{
"query": {
"simple_query_string": {
"query": "stormtrooper category:bloopers"
}
}
}'
curl -XPOST localhost:9200/your_index/_search -d '{
"query": {
"simple_query_string": {
"query": "stormtrooper +tatooine"
}
}
}'
You can also send the query in the query string directly like this:
curl -XPOST localhost:9200/your_index/_search?q=stormtrooper%20%22death%20star%22"

Determining which words were matched in a fuzzy search

I'm running a fuzzy search, and need to see which words were matched. For example, if I am searching for the query testing, and it matches a field with the sentence The boy was resting, I need to be able to know that the match was due to the word resting.
I tried setting the parameter explain = true, but it doesn't seem to contain the information I need. Any thoughts?
Alright, this is what I was looking for:
After a bit of research, I found the Highlighting feature of elasticsearch.
By default it returns a snippet of context surrounding the match, but you can set the fragment size to the query length to return only the exact match. For example:
{
query : query,
highlight : {
"fields" : {
'text' : {
"fragment_size" : query.length
}
}
}
}
Using explain should give you some clues, although not very easily available.
If you run the following, also available at https://www.found.no/play/gist/daa46f0e14273198691a , you should see e.g. description: "weight(text:nesting^0.85714287 in 1) […], description: "weight(text:testing in 1) [PerFieldSimilarity] […] and so on in the hit's _explanation.
#!/bin/bash
export ELASTICSEARCH_ENDPOINT="http://localhost:9200"
# Create indexes
curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{}'
# Index documents
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"type"}}
{"text":"The boy was resting"}
{"index":{"_index":"play","_type":"type"}}
{"text":"The bird was testing while nesting"}
'
# Do searches
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"match": {
"text": {
"query": "testing",
"fuzziness": 1
}
}
},
"explain": true
}
'

Keyword search in ElasticSearch with no regards to the schema

Is it possible to use ElasticSearch to do keyword searches, exactly like in a search engine?
Let me rephrase:
As far as I understand, an ElasticSearch term query requires to specify in which field(s?) to search for keywords.
Given the fact that ElasticSearch can be "schemaless", I wish I could declare a query than can search for keywords in any field.
Is there a syntax for that?
You're looking for the behavior provided by the _all-field, which happens to be on by default:
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-all-field.html
Here's a runnable example: https://www.found.no/play/gist/14688f48c75b9931272b
export ELASTICSEARCH_ENDPOINT="http://localhost:9200"
# Index documents
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"type"}}
{"foo":"bar"}
{"index":{"_index":"play","_type":"type"}}
{"something_else":"foo bar"}
'
# Do searches
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"match": {
"_all": {
"query": "bar"
}
}
}
}
'

Resources