帅哥陈 2023-03-01 20:34 采纳率: 0%
浏览 58
已结题

Elasticsearch复杂排序(非script方式)

问题遇到的现象和发生背景

B2B平台涉及到根据不同的会员进行排序,存在Elasticsearch的数据结构大概是这样:

"id":1,
"price":200,
"unitPriceStrategyList" : [
  {  
    "id" : 27,
    "memberPrice" : 500.0,
    "commodityMemberList" : [
      {
        "memberId" : 157,
        "memberRoleId" : 8
      },
      {
        "memberId" : 300,
        "memberRoleId" : 4
      }
    ],
    "isEnable" : true
  },
  {  
    "id" : 28,
    "memberPrice" : 100.0,
    "commodityMemberList" : [
      {
        "memberId" : 152,
        "memberRoleId" : 8
      },
      {
        "memberId" : 298,
    "memberRoleId" : 4
      }
    ],
    "isEnable" : true
  }
]

根据当前登录人,比如是:memberId=157,memberRoleId=8的人进来,就看到500,如果是memberId=152,memberRoleId=8的人进来,就看到100,其他人不在unitPriceStrategyList.commodityMemberList里面的就看到外面的price价格,也就是200,然后根据看到的价格进行升序和降序排序

尝试过的解决方法

用script方式是可以实现这个需求,但是性能太差了,在生产环境压根就不能用

我想要达到的结果

通过Elasticsearch本身的聚合或者重打分实现上面的需求

  • 写回答

4条回答 默认 最新

  • MarkHan_ 2023-03-01 20:39
    关注

    该回答引用GPTᴼᴾᴱᴺᴬᴵ
    根据您的需求,您可以考虑使用Elasticsearch中的nested数据类型来存储unitPriceStrategyList中的嵌套结构,以便查询时能够准确匹配。建议将unitPriceStrategyList中的数据展开,每一条数据表示一种商品价格策略,以方便查询。例如,将数据转换成以下格式:

    "id":1,
    "price":200,
    "unitPriceStrategyList" : [
      {  
        "id" : 27,
        "memberId" : 157,
        "memberRoleId" : 8,
        "memberPrice" : 500.0,
        "isEnable" : true
      },
      {  
        "id" : 27,
        "memberId" : 300,
        "memberRoleId" : 4,
        "memberPrice" : 500.0,
        "isEnable" : true
      },
      {  
        "id" : 28,
        "memberId" : 152,
        "memberRoleId" : 8,
        "memberPrice" : 100.0,
        "isEnable" : true
      },
      {  
        "id" : 28,
        "memberId" : 298,
        "memberRoleId" : 4,
        "memberPrice" : 100.0,
        "isEnable" : true
      }
    ]
    
    
    

    接下来,您可以使用nested数据类型来定义unitPriceStrategyList的mapping,如下所示:

    PUT /my_index
    {
      "mappings": {
        "properties": {
          "id": {
            "type": "integer"
          },
          "price": {
            "type": "double"
          },
          "unitPriceStrategyList": {
            "type": "nested",
            "properties": {
              "id": {
                "type": "integer"
              },
              "memberId": {
                "type": "integer"
              },
              "memberRoleId": {
                "type": "integer"
              },
              "memberPrice": {
                "type": "double"
              },
              "isEnable": {
                "type": "boolean"
              }
            }
          }
        }
      }
    }
    
    
    

    接下来,您可以使用nested查询来查询符合条件的数据,并使用nested_path参数来指定unitPriceStrategyList的路径。例如,查询memberId=157和memberRoleId=8的数据,可以使用以下查询:

    GET /my_index/_search
    {
      "query": {
        "nested": {
          "path": "unitPriceStrategyList",
          "query": {
            "bool": {
              "must": [
                {
                  "term": {
                    "unitPriceStrategyList.memberId": 157
                  }
                },
                {
                  "term": {
                    "unitPriceStrategyList.memberRoleId": 8
                  }
                }
              ]
            }
          }
        }
      }
    }
    
    
    

    接下来,您可以使用Elasticsearch的排序功能来对查询结果进行排序。例如,使用以下查询对数据按照memberPrice进行升序排序:

    GET index_name/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "unitPriceStrategyList.commodityMemberList.memberId": {
                  "value": 157
                }
              }
            },
            {
              "term": {
                "unitPriceStrategyList.commodityMemberList.memberRoleId": {
                  "value": 8
                }
              }
            }
          ]
        }
      },
      "sort": [
        {
          "unitPriceStrategyList.memberPrice": {
            "order": "asc"
          }
        }
      ]
    }
    
    
    

    这个查询使用bool查询来限制memberId和memberRoleId,然后使用sort来按照unitPriceStrategyList.memberPrice进行升序排序。如果需要降序排序,只需要将"order"的值从"asc"改为"desc"即可。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月9日
  • 创建了问题 3月1日

悬赏问题

  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序
  • ¥15 多址通信方式的抗噪声性能和系统容量对比