【问题标题】:Elasticsearch multiple index queryElasticsearch 多索引查询
【发布时间】:2020-09-30 00:02:31
【问题描述】:

我有一个存储课程详细信息的索引(为简洁起见,我截断了一些属性):

{
  "settings": {
    "index": {
      "number_of_replicas": "1",
      "number_of_shards": "1"
    }
  },
  "aliases": {
    "course": {
      
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "id": {
        "type": "integer"
      },
      "max_per_user": {
        "type": "integer"
      }
    }
  }
}

这里的 max_per_user 是用户可以完成课程的次数。允许用户多次通过课程但不超过课程的 max_per_user 我想跟踪用户与课程的互动。我创建了以下索引来跟踪交互事件。 event_type_id 代表一种交互方式

{
  "settings": {
    "index": {
      "number_of_replicas": "1",
      "number_of_shards": "1"
    }
  },
  "aliases": {
    "course_events": {
      
    }
  },
  "mappings": {
    "properties": {
      "user_progress": {
        "dynamic": "true",
        "properties": {
          "current_count": {
            "type": "integer"
          },
          "user_id": {
            "type": "integer"
          },
          "events": {
            "dynamic": "true",
            "properties": {
              "event_type_id": {
                "type": "integer"
              },
              "event_timestamp": {
                "type": "date",
                "format": "strict_date_time"
              }
            }
          }
        }
      },
      "created_at": {
        "type": "date",
        "format": "strict_date_time"
      },
      "course_id": {
        "type": "integer"
      }
    }
  }
}

current_count 是用户完成整个课程的次数

现在,当我在课程索引上运行搜索时,我还希望能够传入 user_id 并仅获取给定用户的 current_count 小于课程的 max_per_user 的课程

我对课程索引的搜索查询是这样的(为简洁起见,截断了一些过滤器)。这个查询是在用户搜索课程时执行的,所以基本上在执行这个时我会有user_id。

{
  "sort": [
    {
      "id": "desc"
    }
  ],
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "end_date": {
              "gte": "2020-09-28T12:27:55.884Z"
            }
          }
        },
        {
          "range": {
            "start_date": {
              "lte": "2020-09-28T12:27:55.884Z"
            }
          }
        }
      ],
      "must": [
        {
          "term": {
            "is_active": true
          }
        }
      ]
    }
  }
}

我不确定如何构建我的搜索查询,以便能够过滤掉给定 user_id 已达到 max_per_user 的课程。

【问题讨论】:

    标签: elasticsearch elasticsearch-dsl


    【解决方案1】:

    如果我正确理解了这个问题,您希望找到不超过 max_per_user 限制的课程。我的答案是基于相同的:

    考虑到您当前的 Schema 查找所需内容的方法是:

    1. 对于给定的 user_id,查找所有 course_id 及其对应的完成计数
    2. 使用 #1 中获取的数据找出未超过 max_per_user 限制的课程。

    问题来了

    1. 在关系数据库中,可以使用表连接和检查来解决此类用例
    2. Elastic Search 不支持连接,因此无法在此处完成。

    当前架构的糟糕解决方案:

    1. 检查每门课程是否适用。对于 n 门课程,对 E.S 的查询数将与 N 成正比。

    使用当前架构的解决方案:

    1. 在用户课程完成索引(您提到的第二个索引)中,跟踪 max_per_user 并使用如下所示的简单查询来获取所需的课程 ID:

       {
        "size": 10,
        "query": {
          "script": {
             "script": "doc['current_usage'].value<doc['max_per_user'].value && 
             doc['u_id'].value==1" // <======= 1 is the user_id here
      }
      }
      }
      

    【讨论】:

    • 您有权在此处更改架构?例如,与其维护 2 个不同的索引,不如在同一索引中诉诸父子关系?
    • 我可以这样做,但后来我读到了这个 `index.mapping.nested_objects.limit 单个文档可以包含的所有嵌套类型中的嵌套 JSON 对象的最大数量。当文档包含太多嵌套对象时,此限制有助于防止出现内存不足错误。默认值为 10000。` 在 ES 文档中并担心我的主索引(课程索引)中的内存问题
    • 你检查了我提供的解决方案吗?
    • 是的,所以基本上我会调用 ES _search API 两次。在第一次通话中,我将从课程索引中获取所有课程,在第二次通话中(您的解决方案),我将获取对用户有效的所有课程,然后在内存中将其过滤掉。对吗?
    • “当前模式的解决方案”就是我所说的。使用第二个索引上的一个查询将需要为给定用户获取适用/不适用 course_id,然后可用于从第一个索引中获取课程
    猜你喜欢
    • 2018-05-14
    • 1970-01-01
    • 2020-08-08
    • 2014-08-10
    • 2014-05-30
    • 2018-09-08
    • 2020-05-10
    • 1970-01-01
    • 2016-12-28
    相关资源
    最近更新 更多