全书目录

第二十三篇:Elasticsearch 完全指南 —— 全城检索雷达宇宙

第五章:先搭一个小雷达站 —— 一个完整可跑的 Elasticsearch 示例

1 分钟 331 字 第 421 / 962 个阅读单元

下面直接用 Dev Tools 风格,搭一个最小但完整的商品搜索雷达。

http
PUT /city_products
{
  "settings": {
    "analysis": {
      "analyzer": {
        "title_folded": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "title_folded",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "description": {
        "type": "text"
      },
      "brand": {
        "type": "keyword"
      },
      "category": {
        "type": "keyword"
      },
      "price": {
        "type": "integer"
      },
      "rating": {
        "type": "float"
      },
      "in_stock": {
        "type": "boolean"
      },
      "created_at": {
        "type": "date"
      },
      "tags": {
        "type": "keyword"
      }
    }
  }
}

PUT /city_products/_doc/1
{
  "title": "Wireless Noise Cancelling Headphones",
  "description": "Over-ear headphones with deep bass and active noise cancelling.",
  "brand": "AcmeAudio",
  "category": "audio",
  "price": 1299,
  "rating": 4.8,
  "in_stock": true,
  "created_at": "2026-03-01",
  "tags": ["wireless", "anc", "headphones"]
}

PUT /city_products/_doc/2
{
  "title": "Wireless Bluetooth Speaker",
  "description": "Portable speaker with strong bass and all-day battery life.",
  "brand": "AcmeAudio",
  "category": "audio",
  "price": 499,
  "rating": 4.5,
  "in_stock": true,
  "created_at": "2026-03-12",
  "tags": ["wireless", "speaker", "portable"]
}

PUT /city_products/_doc/3
{
  "title": "Studio Monitoring Headphones",
  "description": "Closed-back studio headphones for accurate sound monitoring.",
  "brand": "SoundForge",
  "category": "audio",
  "price": 1799,
  "rating": 4.7,
  "in_stock": false,
  "created_at": "2026-02-20",
  "tags": ["studio", "headphones", "monitoring"]
}

POST /city_products/_refresh

GET /city_products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "wireless noise cancelling",
            "fields": ["title^3", "description"]
          }
        }
      ],
      "filter": [
        { "term": { "category": "audio" } },
        { "term": { "in_stock": true } },
        { "range": { "price": { "lte": 2000 } } }
      ]
    }
  },
  "aggs": {
    "brands": {
      "terms": {
        "field": "brand"
      }
    },
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

这个示例一次性把很多核心点串起来了:

  • city_productsindex
  • 三条商品 JSON 是 document
  • 每个键值对是 field
  • mappings.properties 是字段建档规则
  • titletext,因为要全文搜
  • brandcategorytagskeyword,因为要精确匹配和聚合
  • title.keyword 是同一个值的多重索引方式
  • multi_match 负责全文召回
  • filter 负责精确筛选
  • aggs 负责统计面板

这个例子里,最像用户真实搜索行为的不是 SQL 式“条件命中”,而是:

text
先根据线索召回候选商品
再按结构化条件过滤
最后同时给结果列表和分面统计

这就是 Elasticsearch 的主舞台。