Ordering by an array field when we know which item of the array will be used for ordering


(Ján Paľko) #1

Hi,

Here is a sample document:

{
"descriptions": [
{
"locale": "en-gb",
"description": "Example (English)"
},
{
"locale": "it",
"description": "Example (Italiano)"
},
{
"locale": "fr",
"description": "Example (Francais)"
}
]
}

We have a locale filter, so ES returns the documents which have description
in locale acceptable by user and ordered by his preference e.g. en-gb,en,it
(similar to HTTP Accept-Language header without quality parameter). This
works fine and also searching by description dependent on locale.

On frontend we always use just one description per document, the one with
locale which is the most accurate to user's preference. This is done on
Java side. But what we need is to allow ordering by the descriptions field,
which is array in ES. I know that it isn't possible to order by array
fields as it doesn't make sense. Is there any possibility to filter out
unnecessary descriptions and order by description when we know which
description will be used based on user's language preference?

The last possible solution we would like to avoid is to read all matched
documents and order it on Java side, but we use pagination, and after that
we would read all documents, order them, and return only those which are on
the requested page.

Thanks,
Jan


(Igor Motov) #2

Wouldn't it simplify things if you changed your sample document into
something like this:

{
"descriptions": {
"en-gb": "Example 1 (English)",
"it": "Example 1 (Italiano)",
"fr": "Example 1 (Francais)"
}
}

You can still limit by locale by adding filter descriptions.fr:* for
example or you can store a list of available locales in a separate field.

On Wednesday, March 21, 2012 4:49:10 AM UTC-4, Ján Paľko wrote:

Hi,

Here is a sample document:

{
"descriptions": [
{
"locale": "en-gb",
"description": "Example (English)"
},
{
"locale": "it",
"description": "Example (Italiano)"
},
{
"locale": "fr",
"description": "Example (Francais)"
}
]
}

We have a locale filter, so ES returns the documents which have
description in locale acceptable by user and ordered by his preference e.g.
en-gb,en,it (similar to HTTP Accept-Language header without quality
parameter). This works fine and also searching by description dependent on
locale.

On frontend we always use just one description per document, the one with
locale which is the most accurate to user's preference. This is done on
Java side. But what we need is to allow ordering by the descriptions field,
which is array in ES. I know that it isn't possible to order by array
fields as it doesn't make sense. Is there any possibility to filter out
unnecessary descriptions and order by description when we know which
description will be used based on user's language preference?

The last possible solution we would like to avoid is to read all matched
documents and order it on Java side, but we use pagination, and after that
we would read all documents, order them, and return only those which are on
the requested page.

Thanks,
Jan


(Ján Paľko) #3

Thank you for that, but the problem is more complicated. I've resolved it
by using ScriptSortBuilder where I can take the most relevant description
according to user's language preference and then use the description for
ordering.

On Wednesday, March 21, 2012 4:44:12 PM UTC+1, Igor Motov wrote:

Wouldn't it simplify things if you changed your sample document into
something like this:

{
"descriptions": {
"en-gb": "Example 1 (English)",
"it": "Example 1 (Italiano)",
"fr": "Example 1 (Francais)"
}
}

You can still limit by locale by adding filter descriptions.fr:* for
example or you can store a list of available locales in a separate field.

On Wednesday, March 21, 2012 4:49:10 AM UTC-4, Ján Paľko wrote:

Hi,

Here is a sample document:

{
"descriptions": [
{
"locale": "en-gb",
"description": "Example (English)"
},
{
"locale": "it",
"description": "Example (Italiano)"
},
{
"locale": "fr",
"description": "Example (Francais)"
}
]
}

We have a locale filter, so ES returns the documents which have
description in locale acceptable by user and ordered by his preference e.g.
en-gb,en,it (similar to HTTP Accept-Language header without quality
parameter). This works fine and also searching by description dependent on
locale.

On frontend we always use just one description per document, the one with
locale which is the most accurate to user's preference. This is done on
Java side. But what we need is to allow ordering by the descriptions field,
which is array in ES. I know that it isn't possible to order by array
fields as it doesn't make sense. Is there any possibility to filter out
unnecessary descriptions and order by description when we know which
description will be used based on user's language preference?

The last possible solution we would like to avoid is to read all matched
documents and order it on Java side, but we use pagination, and after that
we would read all documents, order them, and return only those which are on
the requested page.

Thanks,
Jan


(Ján Paľko) #4

For those who are interested in a solution, here it's the sort part from
Java API:

"sort" : [ {
"_script" : {
"script" : "foreach (locale : locales) { foreach (desc :
_source.descriptions) { if (desc.locale.startsWith(locale)) { return
desc.description; } }}",
"type" : "string",
"params" : {
"locales" : [ "en-us", "en", "sk-sk", "it" ]
}
}
} ]

On Thursday, March 22, 2012 1:32:44 PM UTC+1, Ján Paľko wrote:

Thank you for that, but the problem is more complicated. I've resolved it
by using ScriptSortBuilder where I can take the most relevant description
according to user's language preference and then use the description for
ordering.

On Wednesday, March 21, 2012 4:44:12 PM UTC+1, Igor Motov wrote:

Wouldn't it simplify things if you changed your sample document into
something like this:

{
"descriptions": {
"en-gb": "Example 1 (English)",
"it": "Example 1 (Italiano)",
"fr": "Example 1 (Francais)"
}
}

You can still limit by locale by adding filter descriptions.fr:* for
example or you can store a list of available locales in a separate field.

On Wednesday, March 21, 2012 4:49:10 AM UTC-4, Ján Paľko wrote:

Hi,

Here is a sample document:

{
"descriptions": [
{
"locale": "en-gb",
"description": "Example (English)"
},
{
"locale": "it",
"description": "Example (Italiano)"
},
{
"locale": "fr",
"description": "Example (Francais)"
}
]
}

We have a locale filter, so ES returns the documents which have
description in locale acceptable by user and ordered by his preference e.g.
en-gb,en,it (similar to HTTP Accept-Language header without quality
parameter). This works fine and also searching by description dependent on
locale.

On frontend we always use just one description per document, the one
with locale which is the most accurate to user's preference. This is done
on Java side. But what we need is to allow ordering by the descriptions
field, which is array in ES. I know that it isn't possible to order by
array fields as it doesn't make sense. Is there any possibility to filter
out unnecessary descriptions and order by description when we know which
description will be used based on user's language preference?

The last possible solution we would like to avoid is to read all matched
documents and order it on Java side, but we use pagination, and after that
we would read all documents, order them, and return only those which are on
the requested page.

Thanks,
Jan


(system) #5