Incorrect AND/OR priority in query_string - elasticsearch

Today I found weird behavior of elasticsearch 1.5.2
I'm indexing 2 documents:
POST http://localhost:9200/index/type {
"string":"a b"
}
POST http://localhost:9200/index/type {
"string" : "c d"
}
And following query returns no hits (why?):
POST http://localhost:9200/index/type/_search
{
"query" : {
"query_string" : {
"query_string" : {
"query" : "string:a AND string:b OR string:c AND string:d"
}
}
}
}
But the same query with brackets over ANDs returns 2 documents, as expected:
POST http://localhost:9200/index/type/_search
{
"query" : {
"query_string" : {
"query_string" : {
"query" : "(string:a AND string:b) OR (string:c AND string:d)"
}
}
}
}
According to specification
(https://www.elastic.co/guide/en/elasticsearch/reference/1.5/query-dsl-query-string-query.html)
NOT takes precedence over AND, which takes precedence over OR
so both queries must return same result.
Is it bug or I've missed something?
Thanks in advance!

The query mentioned by you
"query" : "string:a AND string:b OR string:c AND string:d"
works as all a,b and d should be present in string and if c is present then that document will be boosted up .
That's why it looks for a,b and d which it doesn't find in any document and displays no result.
As per the specification here:
AND and OR can affect the terms to the left and right.
You can also refer this

Related

Combining results of two queries

I'm using Kibana v6.1.1 and trying to get within one GET request two different queries in order to use the "must" or "should" terms more than once.
When I run this query under "Dev Tools" in the Kibana, it works.
When I want to apply this "double query" (without the GET line of course) under "Discover"->"Add a filter"->"Edit filter"->"Edit Query DSL", it doesn't accept the syntax {} in order to create an 'OR' between the queries.
It is necessary that these two "must" terms will be separated but stay in the same filter.
GET _my_index/_search
{
"query" : {
"bool" : {
"must" : [{
...
}]
}
}
}
{}
{
"query" : {
"bool" : {
"must" : [{
...
}]
}
}
}
P.S.
Using the simple_query_string doesn't seem to solve the problem and so far, I couldn't find the way to combine these two queries.
I'm not sure what you actually want to achieve. Use the following if at least one of the shoulds has to match (there is an implicit minimum_should_match if there are no other conditions, but you can also set an explicit value for that):
{
"query" : {
"bool" : {
"should" : [
{
...
},
{
...
}
]
}
}
}
If you want to run independent queries, use a multi search.

Nested filter returns wrong result when Object name is not given to search

Using elastic search, I am trying to get data for nested object
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
NestedQueryBuilder nestedBuilder = QueryBuilders.nestedQuery("Attributes", boolBuilder);
boolBuilder.must(QueryBuilders.termQuery("Attributes.attributeId", "1001"));
Result comes if the query is like this,
{
"nested" : {
"query" : {
"bool" : {
"must" : [ {
"term" : {
"Attributes.attributeId" : "1001"
}
]
}
},
"path" : "Attributes"
}'
Result not coming if the query is like this,
{
"nested" : {
"query" : {
"bool" : {
"must" : [ {
"term" : {
"attributeId" : "1001"
}
]
}
},
"path" : "Attributes"
}
Can somebody help me.Here i have to get result without using "Attributes.attributeId".ie. using "attributeId" alone data have to come.
This is expected as per the nested query documentation
The query path points to the nested object path, and the query (or
filter) includes the query that will run on the nested docs matching
the direct path, and joining with the root parent docs. Note that any
fields referenced inside the query must use the complete path (fully
qualified).

How to use elastic search for advanced queries:

I'm using elasticsearch. I'm already pretty deep into it but I'm very confused as to how to go about writing advanced queries. There are queries / filters / etc. I'm confused as to how to proceed.
I have a schema that looks like this:
photos: {people: [{person_id: 1, person_name:"john kealy"}],
tags: [{tag_id: 1, tag_name:"other tag"},
by_line: "John D Kealy/My website.com",
location: "Some Place OUt West"]
I need to be able to string together these queries dynamically ALWAYS pulling in FULL MATCHES, e.g. I would like to search for
people.person_id: [1,2] (pulls in only photos with BOTH or more peole)
tags.tag_id: [1,2,3] (pulls in only photos with all three or more tags)
by_line: "John D. Kealy/My Website.com" (the full name including the slash)
location: "some place out west"
I would like to write one query with all these items. I need to include the slash in "by_line", i don't care up upper or lower case. I need the exact match "some place out west". What do I use here? Queries or filters / filtered?
General guidelines for bool filters/queries can be found here.
If you are constructing an "exact match" query, you can often use the term filter (or query).
If you are constructing a search that requires a solid performance speed wise, a filtered query is often advisable, as filters are set before the query is run, often improving performance.
As for your specific example, the below filters should work, throw it around a matchAll query or anything else you need [With the non-analyzed by_line field, the analyzed one has a query). This should give you an idea as how to construct future queries:
NOTE: This assumes that your by_line field is not analyzed. The double slash will escape your slash delimiter, if you are using an analyzed field you must use a match query.
Without analyzer on by_line
{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"must" : [
{ "terms" : {"people.person_id" : ["1", "2"]}},
{ "terms" : {"tags.tag_id" : ["1", "2", "3"]}},
{ "term" : {"by_line" : "John D. Kealy\\/My Website.com"}},
{ "term" : {"location" : "some place out west"}}
]
}
}
}
}
}
I will keep the above there for future readers, however I see in your post history that you are using the standard analyzer, your query should be structured as follows.
With analyzer on by_line
{
"query" : {
"filtered" : {
"query": {
"match": {
"by_line": "John Kealy/BFA.com"
}
},
"filter" : {
"bool" : {
"must" : [
{ "terms" : {"people.person_id" : ["1", "2"]}},
{ "terms" : {"tags.tag_id" : ["1", "2", "3"]}},
{ "term" : {"location" : "some place out west"}}
]
}
}
}
}
}

How to use lucene SpanQuery in ElasticSearch

For my project, I thought of using Span Near Queries of ElasticSearch, with the constraint that is, certain tokens may have to searched with Fuzziness. I was able to generate a set of SpanQuery (org.apache.lucene.search.spans.SpanQuery) objects some with fuzzy enabled, some without. I couldn't figure out how to use these set of SpanQueries in ElasticSearch spanNearQuery.
Can someone help me out with right pointers to samples or docs. And is there any way to construct ES SpanNearQueryBuilder with some clauses fuzzy enabled ?
You can wrap an fuzzy query into a span query with Span Multi Term Query:
{
"span_near" : {
"clauses" : [
{ "span_term" : { "field" : "value1" } },
{ "span_multi" :
"match" : {
"prefix" : { "user" : { "field" : "value2" } }
}
}
],
...
}
}

In elasticsearch after adding a new field to a doc, cannot find with "exists" filter

I'm adding a field to a doc like this:
curl -XPOST 'http://localhost:9200/imap_email/imap_bruce/12/_update' -d '{
"script" : "ctx._source.simperium = \"12345\""
}'
Looking at that doc, I can verify that it has added the field "simperium". The following query (and the many variations of it I've tried) simply return everything in my index.
{
"constant_score" : {
"filter" : {
"exists" : { "field" : "simperium" }
}
}
}
What do I need to do to get a strict list of all docs that do or don't have a specific field?
The majority of Elasitcsearch examples exclude the outer "query" : {} object for brevity. It's very annoying when starting out, but eventually you learn to accept it.
You most likely wanted this:
{
"query" : {
"constant_score" : {
"filter" : {
"exists" : { "field" : "simperium" }
}
}
}
}

Resources