练习项目跟进es查询(day10)
es查询代码es_data_router.get(/search, summary职位搜索) async def search_jobs( # ---------- 关键词 ---------- keyword: Optional[str] Query(None, description搜索关键词如 Java、前端), # ---------- 筛选 ---------- work_location: Optional[str] Query(None, description工作地点精确匹配), edu_require: Optional[str] Query(None, description学历要求), exp_require: Optional[str] Query(None, description经验要求), industry_id: Optional[int] Query(None, description行业ID), company_scale: Optional[int] Query(None, description公司规模枚举值), financing_stage: Optional[int] Query(None, description融资阶段枚举值), status: Optional[int] Query(1, description职位状态默认1招聘中), # ---------- 分页 / 排序 ---------- page: int Query(1, ge1, description页码), page_size: int Query(10, ge1, le50, description每页条数), sort: str Query(time, description排序score相关度time发布时间), es_client: AsyncElasticsearch Depends(es_client_depend), ): 职位搜索思路 1. bool.must/should关键词 multi_match有 keyword 才加 2. bool.filter城市、学历、状态等精确条件不参与算分 3. from/size分页 4. sort有词按相关度或按 publish_time # 索引不存在时友好提示 if not await es_client.indices.exists(indexBOSS_JOB_INDEX_NAME): return { code: 0, message: f索引 {BOSS_JOB_INDEX_NAME} 不存在请先创建并同步数据, } must_clauses: list[dict[str, Any]] [] filter_clauses: list[dict[str, Any]] [] # ----- 1关键词打在多个 text 字段职位名称加权 ----- if keyword and keyword.strip(): must_clauses.append( { multi_match: { query: keyword.strip(), fields: [ job_name^3, # 名称命中权重更高 job_desc^2, duty_require, enterprise_name, industry_name, ], type: best_fields, operator: and, # 可按需改成 or召回更宽 } } ) # ----- 2硬筛选全部放 filter ----- if status is not None: filter_clauses.append({term: {status: status}}) if work_location: filter_clauses.append({term: {work_location: work_location}}) if edu_require: filter_clauses.append({term: {edu_require: edu_require}}) if exp_require: filter_clauses.append({term: {exp_require: exp_require}}) if industry_id is not None: filter_clauses.append({term: {industry_id: industry_id}}) if company_scale is not None: filter_clauses.append({term: {enterpriseInfo_company_scale: company_scale}}) if financing_stage is not None: filter_clauses.append({term: {enterpriseInfo_financing_stage: financing_stage}}) # ----- 3组装 bool ----- bool_query: dict[str, Any] {} if must_clauses: bool_query[must] must_clauses if filter_clauses: bool_query[filter] filter_clauses # 既无关键词也无筛选时匹配全部仍建议至少有默认 status filter query: dict[str, Any] {bool: bool_query} if bool_query else {match_all: {}} # ----- 4排序 ----- # 有关键词且 sortscore → 按相关度否则按发布时间倒序 if sort score and keyword: sort_clause: Any [_score, {publish_time: {order: desc, missing: _last}}] else: sort_clause [{publish_time: {order: desc, missing: _last}}] # ----- 5分页ES 用 from / size ----- from_ (page - 1) * page_size # 列表页只取卡片字段减小 _source source_fields [ job_id, job_name, work_location, min_salary, max_salary, salary_times, edu_require, exp_require, job_tags, status, publish_time, enterprise_id, enterprise_name, enterprise_city_name, enterpriseInfo_company_scale, enterpriseInfo_financing_stage, industry_id, industry_name, ] resp await es_client.search( indexBOSS_JOB_INDEX_NAME, queryquery, sortsort_clause, from_from_, sizepage_size, sourcesource_fields, track_total_hitsTrue, # 拿到准确 total ) hits resp.get(hits, {}) total hits.get(total, {}) # ES 7 total 一般是 {value: n, relation: eq} total_count total.get(value, 0) if isinstance(total, dict) else int(total or 0) lists [] for hit in hits.get(hits, []): item hit.get(_source) or {} item[_score] hit.get(_score) # 可选方便调相关度 lists.append(item) return { code: 1, message: success, data: { lists: lists, page_info: { page: page, page_size: page_size, total_count: total_count, total_page: (total_count page_size - 1) // page_size if page_size else 0, }, }, }雪花算法import time import threading class SnowflakeSingleton: 单例模式的雪花算法生成唯一ID工具类 _instance None _lock threading.Lock() # 单例模式的线程锁 # 起始时间戳 (2020-01-01 00:00:00) START_TIMESTAMP 1577808000000 # 各部分位数 SEQUENCE_BITS 12 # 序列号位数 WORKER_ID_BITS 10 # 工作节点ID位数 # 最大取值计算 MAX_WORKER_ID -1 ^ (-1 WORKER_ID_BITS) # 1023 MAX_SEQUENCE -1 ^ (-1 SEQUENCE_BITS) # 4095 # 移位偏移量计算 WORKER_ID_SHIFT SEQUENCE_BITS # 12 TIMESTAMP_LEFT_SHIFT SEQUENCE_BITS WORKER_ID_BITS # 22 def __new__(cls, worker_idNone): 单例模式实现确保只创建一个实例 with cls._lock: # 如果实例不存在则创建 if not cls._instance: # 首次创建时必须提供worker_id if worker_id is None: raise ValueError(首次初始化必须提供worker_id参数) cls._instance super().__new__(cls) # 初始化实例变量 cls._instance.worker_id worker_id cls._instance.last_timestamp -1 # 上次生成ID的时间戳 cls._instance.sequence 0 # 序列号 cls._instance.id_lock threading.Lock() # 生成ID的线程锁 # 如果已经存在实例再次传入的worker_id必须与初始一致 elif worker_id is not None and worker_id ! cls._instance.worker_id: raise ValueError(f雪花算法实例已初始化worker_id必须为{cls._instance.worker_id}) return cls._instance classmethod def get_instance(cls, worker_idNone): 获取单例实例的便捷方法 return cls(worker_id) def _gen_timestamp(self): 生成当前时间戳毫秒 return int(time.time() * 1000) def get_id(self): 生成下一个唯一ID with self.id_lock: # 确保线程安全 timestamp self._gen_timestamp() # 处理系统时钟回退 if timestamp self.last_timestamp: raise RuntimeError( f系统时钟回退拒绝生成ID。时间差: {self.last_timestamp - timestamp}毫秒 ) # 处理同一毫秒内的序列号 if timestamp self.last_timestamp: self.sequence (self.sequence 1) self.MAX_SEQUENCE # 序列号达到最大值等待下一毫秒 if self.sequence 0: timestamp self._til_next_millis(self.last_timestamp) else: # 不同时间戳序列号重置为0 self.sequence 0 # 更新上次生成ID的时间戳 self.last_timestamp timestamp # 组合生成ID snowflake_id ( ((timestamp - self.START_TIMESTAMP) self.TIMESTAMP_LEFT_SHIFT) | (self.worker_id self.WORKER_ID_SHIFT) | self.sequence ) return snowflake_id def _til_next_millis(self, last_timestamp): 阻塞到下一个毫秒直到获得新的时间戳 timestamp self._gen_timestamp() while timestamp last_timestamp: timestamp self._gen_timestamp() return timestamp # 调用方法示例 if __name__ __main__: # 初始化单例首次调用必须提供worker_id snowflake SnowflakeSingleton.get_instance(worker_id1) # 生成10个ID并打印 for _ in range(10): print(f生成的ID: {snowflake.get_id()}) # 在其他地方获取实例无需再次提供worker_id another_instance SnowflakeSingleton.get_instance() print(f\n验证单例: {snowflake is another_instance}) # 应输出True # 多线程测试 def generate_ids(count): ids [] for _ in range(count): ids.append(SnowflakeSingleton.get_instance().get_id()) return ids # 创建多个线程同时生成ID threads [] for i in range(5): t threading.Thread(targetgenerate_ids, args(1000,)) threads.append(t) t.start() for t in threads: t.join() print(\n多线程ID生成测试完成)

相关新闻

Android编译失败:全面解析Execution failed for task ‘:app:compileDebugJavaWithJavac‘

Android编译失败:全面解析Execution failed for task ‘:app:compileDebugJavaWithJavac‘

1. 项目概述:当你的Android项目编译突然“罢工” “Execution failed for task ‘:app:compileDebugJavaWithJavac‘”——这行红彤彤的报错信息,对于任何一个Android开发者来说,都再熟悉不过了。它就像一个不请自来的“老朋友”&#xff0c…

2026/7/31 5:50:51 阅读更多 →
企业 AI 落地,第一件事不是买模型,而是建好企业知识库

企业 AI 落地,第一件事不是买模型,而是建好企业知识库

企业 AI 落地,第一件事不是买模型,而是建好企业知识库 大家好,我是老王,一个在技术圈摸爬滚打多年的程序员。这两年,AI 大模型火得不行,到处都在谈“企业 AI 落地”。很多老板二话不说,先砸钱买…

2026/7/31 5:50:51 阅读更多 →
C#异常处理实战指南:从try-catch到全局异常处理

C#异常处理实战指南:从try-catch到全局异常处理

1. 项目概述:为什么异常处理是C#开发的“安全带”干了这么多年C#开发,从桌面程序到Web API,再到各种后台服务,我越来越觉得,异常处理(Exception Handling)就像是程序员给代码系上的“安全带”。…

2026/7/31 5:50:51 阅读更多 →

最新新闻

Web安全入门实战:HackThisSite基础关卡漏洞原理与渗透测试详解

Web安全入门实战:HackThisSite基础关卡漏洞原理与渗透测试详解

1. 项目概述:从零开始的Web安全实战演练场如果你对网络安全感兴趣,刷过一些理论,看过不少“从入门到入狱”的段子,但一打开那些复杂的靶场或者工具就感到无从下手,那么你找对地方了。今天我们不谈空泛的理论&#xff0…

2026/7/31 6:19:01 阅读更多 →
Footprint Tool 3基础操作指南:从数据导入到结果分析的完整流程

Footprint Tool 3基础操作指南:从数据导入到结果分析的完整流程

1. 先搞清楚 Footprint Tool 3 到底解决什么问题 Footprint Tool 3 这类工具,从名字就能看出是用于计算、分析或管理某种“足迹”的专业软件。在实际项目中,足迹分析可能涉及碳足迹、环境足迹、资源消耗足迹、甚至项目进度足迹等多个维度。这个 UNIT 2 的…

2026/7/31 6:19:01 阅读更多 →
Python循环全解析:while与for循环的核心原理、应用场景与避坑指南

Python循环全解析:while与for循环的核心原理、应用场景与避坑指南

1. 循环的本质:为什么我们需要重复执行代码?写代码最怕什么?不是语法错误,也不是逻辑复杂,而是写重复的代码。想象一下,你需要打印数字1到100。如果不用循环,你得老老实实写100行print(1)、prin…

2026/7/31 6:19:01 阅读更多 →
智慧园区IOC:数字孪生赋能园区精细化运营

智慧园区IOC:数字孪生赋能园区精细化运营

智慧园区IOC(智能运营中心)是园区管理的“大脑”。CIMPro孪大师为构建园区IOC提供了高效、低成本的开发方案。平台以园区实体模型为基础,精确构建1:1的三维数字模型,并深度整合产业动态、资产管理、基础设施、能源效率和安全防护等…

2026/7/31 6:19:01 阅读更多 →
C++初始化与赋值底层原理:从汇编视角看性能优化与内存管理

C++初始化与赋值底层原理:从汇编视角看性能优化与内存管理

1. 从“定义”到“执行”:为什么我们需要深究初始化与赋值?在编程的世界里,我们每天都在和变量打交道。定义一个变量,给它一个值,这似乎是再自然不过的操作。但你是否想过,当你写下int a 10;这行简单的 C …

2026/7/31 6:19:01 阅读更多 →
STC89C52单片机驱动DS18B20温度传感器:单总线通信协议详解与实战

STC89C52单片机驱动DS18B20温度传感器:单总线通信协议详解与实战

1. 项目概述:从“点灯”到“测温”的进阶玩过51单片机的朋友,大多都是从点亮一个LED灯开始的。当流水灯、数码管、按键这些基础外设都玩转之后,下一个让你既兴奋又有点头疼的挑战,往往就是与各种传感器打交道。而DS18B20这款数字温…

2026/7/31 6:18:00 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻