Is it possible to do nested sort with a conditional query on a sort element

时间:2016-08-31 18:03:34

标签: elasticsearch

we have following structure in an index - following is only a partial and doc relevant for this question.

"instance" : {
  "id" : 1,
  {"instFields": [
  {
    "sourceFieldId": 2684,
    "fieldValue": "false",
    "fieldBoolean": false
  },
  {
    "sourceFieldId": 1736,
    "fieldValue": "DODGE",
    "fieldString": "DODGE"
  },

  {
    "sourceFieldId": 1560,
    "fieldValue": "GRAY",
    "fieldString": "GRAY"
  },
  {
    "sourceFieldId": 1558,
    "fieldValue": "CHALLENGER",
    "fieldString": "CHALLENGER"
  },
  {
    "sourceFieldId": 1556,
    "fieldValue": "2010",
    "fieldDouble": 2010
  }

  ]
}

first user query is give me all instances where sourceFieldId=1736 - this returns all the DODGE instances[] - all this is working fine with an appripriate Elastic Search query. now when user is seeing all DODGE records - user wants to sort by any of those sourceFieldIds for e.g. say user is wanting to sort results by - color - sourceFieldId=1560.

say we have following sort query

 {
  "query": {
    "bool": {
    "filter": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "filtered": {
                "query": {
                  "match_all": {}
                },
                "filter": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "instance.dataSourceId": "196"
                        }
                      },
                      {
                        "term": {
                          "instance.dsTypeId": "5"
                        }
                      },
                      {
                        "nested": {
                          "query": {
                            "filtered": {
                              "query": {
                                "match_all": {}
                              },
                              "filter": {
                                "bool": {
                                  "must": [
                                    {
                                      "term": {
                                        "instance.instFields.sourceFieldId": "1558"
                                      }
                                    },
                                    {
                                      "term": {
                                        "instance.instFields.fieldString.raw": "challenger"
                                      }
                                    }
                                  ]
                                }
                              }
                            }
                          },
                          "path": "instance.instFields"
                        }
                      }
                    ]
                  }
                }
              }
            },
            "path": "instance",
            "inner_hits": {
              "name": "inner_data"
            }
          }
        },
        {
          "nested": {
            "query": {
              "bool": {
                "should": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "instance.entitlements.roleId": {
                            "query": "1",
                            "type": "boolean"
                          }
                        }
                      },
                      {
                        "match": {
                          "instance.entitlements.read": {
                            "query": "true",
                            "type": "boolean"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            },
            "path": "instance.entitlements"
          }
        }
      ]
    }
  }
}
},
"sort": {
"instance.instFields.fieldString.raw": {
  "order": "asc",
  "nested_path": "instance.instFields",
  "nested_filter": {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "nested": {
                "query": {
                  "filtered": {
                    "query": {
                      "match_all": {}
                    },
                    "filter": {
                      "bool": {
                        "must": [
                          {
                            "term": {
                              "instance.dataSourceId": "196"
                            }
                          },
                          {
                            "term": {
                              "instance.dsTypeId": "5"
                            }
                          },
                          {
                            "nested": {
                              "query": {
                                "filtered": {
                                  "query": {
                                    "match_all": {}
                                  },
                                  "filter": {
                                    "bool": {
                                      "must": [
                                        {
                                          "term": {
                                            "instance.instFields.sourceFieldId": "1558"
                                          }
                                        },
                                        {
                                          "term": {
                                            "instance.instFields.fieldString.raw": "challenger"
                                          }
                                        }
                                      ]
                                    }
                                  }
                                }
                              },
                              "path": "instance.instFields"
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "path": "instance",
                "inner_hits": {
                  "name": "inner_data1"
                }
              }
            },
            {
              "nested": {
                "query": {
                  "bool": {
                    "should": {
                      "bool": {
                        "must": [
                          {
                            "match": {
                              "instance.entitlements.roleId": {
                                "query": "1",
                                "type": "boolean"
                              }
                            }
                          },
                          {
                            "match": {
                              "instance.entitlements.read": {
                                "query": "true",
                                "type": "boolean"
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                },
                "path": "instance.entitlements"
              }
            }
          ]
        }
      }
    }
  }
 }
}
}

resulting docs must return entire instance with all the soureceFields - as on a user page it displays other values of DODGE as well.

now issue is- sort query still has to have knowledge to sort where - "sourceFieldId": 1560 (which is a sourceFieldId for color) to sort on color

is there a way to achieve such a sort query in ES without using dynamic scripting/dynamic templating? something like

"sort": {
   "instance.instFields.fieldString.raw": (where sourceFieldId=1560?)

1 个答案:

答案 0 :(得分:1)

应该可以使用sort

中的nested_filter选项实现此目的

来自文档:

  

nested_filter嵌套路径中内部对象的过滤器   应匹配,以便将其字段值用于   按分类帐户。常见的情况是重复查询/过滤内部   嵌套过滤器或查询。默认情况下,没有nested_filter处于活动状态。

例如,要对颜色字段进行排序,它将是:

{
   "sort": {
      "instance.instFields.fieldValue.raws": {
         "order": "asc",
         "nested_path": "instance.instFields",
         "nested_filter": {
            "term": {
               "instance.instFields.sourceFieldId": "1560"
            }
         }
      }
   }
}

被修改

"sort": [{
      "instance.instFields.fieldValue": {
         "order": "asc",
         "nested_path": "instance.instFields",
         "nested_filter": {
            "term": {
               "instance.instFields.sourceFieldId": "1560"
            }
         }
      }
   },
   {
      "instance.instFields.fieldValue": {
         "order": "asc",
         "nested_path": "instance.instFields",
         "nested_filter": {
            "term": {
               "instance.instFields.sourceFieldId": "1558"
            }
         }
      }
   }

   ]