Help with a UNION style search

Hi there,

Unfortunately I don't have a set of CURL steps available at the moment so I
will do my best to succinctly describe my situation.

We currently have two mappings, one for beneficiaries, the other for
campaigns.

When searching for a term, such as "heart", I am trying to return all
results that match this term from both mappings, and if the potential
result is from the campaigns mapping, also ensure that the campaign is
'active' (current date is between start & end date of campaign).

This is query I have constructed:

{
"min_score": 0.99,
"from": 0,
"size": 9,
"query": {
"query_string": {
"query": "heart",
"default_operator": "OR",
"fields": [
"beneficiaries.name.search",
"beneficiaries.categories.search^2",
"campaigns.beneficiary.search",
"campaigns.categories.search^2"
]
}
},
"filter": {
"and": [
{
"terms": {
"_type": [
"beneficiaries",
"campaigns"
]
}
},
{
"range": {
"start_date.value": {
"lte": "now",
"gte": "19700101T100000Z"
}
}
},
{
"range": {
"end_date.value": {
"lte": "20150429T161301Z",
"gte": "now"
}
}
}
]
}
}

This query "works", but fails to return any results from the beneficiaries
mapping.

I think where this query is going wrong is it trying to match the range
even though those fields don't exist on the beneficiaries mapping.

Is there some sort of way to require the result to match these fields
(start_date, end_date range) if they exist (ie. _type = "campaigns") and
ignore them otherwise?

Thanks for any help!

Cheers,

Brendan

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Do the date fields always exist in the campaign data and always do not
exist in the beneficiaries? If so, you can add a missing filter to your
existing filter. You can change your and filter into a bool filter and add
it as an should clause or wrap your existing and filter in an or filter.

--
Ivan

On Sun, Apr 28, 2013 at 11:19 PM, brendan.rb@randb.com.au wrote:

Hi there,

Unfortunately I don't have a set of CURL steps available at the moment so
I will do my best to succinctly describe my situation.

We currently have two mappings, one for beneficiaries, the other for
campaigns.

When searching for a term, such as "heart", I am trying to return all
results that match this term from both mappings, and if the potential
result is from the campaigns mapping, also ensure that the campaign is
'active' (current date is between start & end date of campaign).

This is query I have constructed:

{
"min_score": 0.99,
"from": 0,
"size": 9,
"query": {
"query_string": {
"query": "heart",
"default_operator": "OR",
"fields": [
"beneficiaries.name.search",
"beneficiaries.categories.search^2",
"campaigns.beneficiary.search",
"campaigns.categories.search^2"
]
}
},
"filter": {
"and": [
{
"terms": {
"_type": [
"beneficiaries",
"campaigns"
]
}
},
{
"range": {
"start_date.value": {
"lte": "now",
"gte": "19700101T100000Z"
}
}
},
{
"range": {
"end_date.value": {
"lte": "20150429T161301Z",
"gte": "now"
}
}
}
]
}
}

This query "works", but fails to return any results from the beneficiaries
mapping.

I think where this query is going wrong is it trying to match the range
even though those fields don't exist on the beneficiaries mapping.

Is there some sort of way to require the result to match these fields
(start_date, end_date range) if they exist (ie. _type = "campaigns") and
ignore them otherwise?

Thanks for any help!

Cheers,

Brendan

--
You received this message because you are subscribed to the Google Groups
"elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Hi Ivan,

Thanks for the reply. I managed to get it working using and/or:

{
"from": 0,
"size": 9,
"query": {
"query_string": {
"query": "heart",
"default_operator": "OR",
"fields": [
"beneficiaries.name.search",
"beneficiaries.categories.search^2",
"campaigns.beneficiary.search",
"campaigns.categories.search^2"
]
}
},
"filter": {
"or": [
{
"terms": {
"_type": [
"beneficiaries"
]
}
},
{
"and": [
{
"terms": {
"_type": [
"campaigns"
]
}
},
{
"range": {
"start_date.value": {
"lte": "now",
"gte": "19700101T100000Z"
}
}
},
{
"range": {
"end_date.value": {
"lte": "20150429T161301Z",
"gte": "now"
}
}
}
]
}
]
}
}

I did see the docs on the missing filter, but I wasn't sure on how to apply
in this scenario. Could you show an brief example? I'm curious :slight_smile:

Thanks again,

Brendan

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Hi Ivan,

I now think I know why you mentioned the missing filter. Some campaigns
don't have start/end dates, so in this scenario we need a query that will
use start/end dates if they exist, and if they are missing, just include
that result anyway. Could you show an example of this in action?

Reading thishttp://www.elasticsearch.org/guide/reference/query-dsl/missing-filter/,
is it just another item in the "and" of the campaign related filters?

Thanks for your time,

Brendan

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

I originally suggested the missing filter because I missed the fact that
your "mappings" are essentially different types. A different mapping
doesn't have to be a different type, but it should be. Your second solution
is ideal since it you can filter on the type.

As far as the missing filter goes, you are correct and you should just add
it to your existing filters. Something like
(BENEFICIARY || (CAMPAIGN && (some_range_filter || missing filter))

--
Ivan

On Tue, Apr 30, 2013 at 12:12 AM, brendan.rb@randb.com.au wrote:

Hi Ivan,

I now think I know why you mentioned the missing filter. Some campaigns
don't have start/end dates, so in this scenario we need a query that will
use start/end dates if they exist, and if they are missing, just include
that result anyway. Could you show an example of this in action?

Reading thishttp://www.elasticsearch.org/guide/reference/query-dsl/missing-filter/,
is it just another item in the "and" of the campaign related filters?

Thanks for your time,

Brendan

--
You received this message because you are subscribed to the Google Groups
"elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.