Reputation: 17793
I am looking for a way to do this. I need to show all experts inside the users mapping. (Experts are documents with field role equals 3). But while showing the experts, I need to show experts having "Linkedin" inside their social medias (social_medias is an array field in the users mapping) first and those without "Army" afterwards. For ex:, I have 5 documents:
[
{
role: 3,
name: "David",
social_medias: ["Twitter", "Facebook"]
},
{
role: 3,
name: "James",
social_medias: ["Facebook", "Linkedin"]
},
{
role: 3,
name: "Michael",
social_medias: ["Linkedin", "Facebook"]
},
{
role: 3,
name: "Peter",
social_medias: ["Facebook"]
},
{
role: 3,
name: "John",
social_medias: ["Facebook", "Twitter"]
},
{
role: 2,
name: "Babu",
social_medias: ["Linkedin", "Facebook"]
}
]
So, I want to get documents with role 3 and while fetching it, documents having "Linkedin" in social media should come first. So, the output after query should be in this order:
[
{
role: 3,
name: "James",
social_medias: ["Facebook", "Linkedin"]
},
{
role: 3,
name: "Michael",
social_medias: ["Linkedin", "Facebook"]
},
{
role: 3,
name: "David",
social_medias: ["Twitter", "Facebook"]
},
{
role: 3,
name: "Peter",
social_medias: ["Facebook"]
},
{
role: 3,
name: "John",
social_medias: ["Facebook", "Twitter"]
}
]
I am trying with function_score
now. I can specify a column to have more priority in function_score, but cant figure out how to specify condition based priority.
Upvotes: 0
Views: 642
Reputation: 52368
Why not let the default sorting in ES (sort by score) do the job for you, without custom ordering or custom scoring:
GET /my_index/media/_search
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{"match": {"social_medias": "Linkedin"}},
{"match_all": {}},
{"query_string": {
"default_field": "social_medias",
"query": "NOT Army"
}}
]
}
},
"filter": {
"term": {
"role": "3"
}
}
}
}
}
The query above filters for "role":"3"
and then in a should
clause it basically says: if the documents match social_medias
field with value Linkedin
then give them a score based on this matching. To, also, include all others documents that don't match Linkedin
, add another should
for match_all
. Now, everything that matches match_all
gets a score. If those documents, also, match Linkedin
then they get an additional score, thus making them score higher and be first in the list of results.
Upvotes: 3