You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET项目中Elasticsearch获取文档路由异常问题求助

问题分析与解决方案

核心问题原因

你遇到的路由错误,大概率是以下两个原因之一:

  1. 请求的id参数为空:跳转编辑页面时未正确传递id参数,导致Elasticsearch请求路径缺失文档ID,触发No route错误。
  2. 混淆了Elasticsearch文档ID与自定义字段:你添加数据时用的POST superheroes/_doc/1中的1是Elasticsearch的文档_id,而实体类里的Id是自定义字段(值为one),二者并非同一概念,若传递的id参数与文档_id不匹配,也会引发异常。

解决步骤

步骤1:验证请求参数有效性

首先确保跳转编辑页面时,URL携带了正确的id参数,比如:

  • 如果根据文档_id查询,URL应为:Edit.aspx?id=1
  • 如果根据自定义Id字段查询,URL应为:Edit.aspx?id=one

同时在代码中添加参数空判断,避免空值请求:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var heroId = Request.QueryString["id"];
        if (string.IsNullOrEmpty(heroId))
        {
            litInfo.Text = "缺少有效英雄ID参数";
            return;
        }

        // 后续Elasticsearch查询逻辑
    }
}

步骤2:修正Elasticsearch查询逻辑

根据你的需求选择对应查询方式:

方式一:按文档_id查询(对应添加数据时的1)

简化NEST的Get调用(已设置默认索引,无需重复指定),并增加查询结果判断:

var settings = new ConnectionSettings(new Uri("http://localhost:9200")).DefaultIndex("superheroes");
var client = new ElasticClient(settings);

var getResponse = client.Get<esHero>(heroId);
if (getResponse.Found)
{
    LitID.Text = getResponse.Source.Id;
    LitName.Text = getResponse.Source.name;
    LitPowers.Text = getResponse.Source.powerstats;
    LitOccupation.Text = getResponse.Source.occupation;
}
else
{
    litInfo.Text = "未找到指定英雄";
}

方式二:按自定义Id字段查询(对应实体中的one)

此时不能用Get方法(Get仅支持按文档_id查询),改用Search方法:

var settings = new ConnectionSettings(new Uri("http://localhost:9200")).DefaultIndex("superheroes");
var client = new ElasticClient(settings);

var searchResponse = client.Search<esHero>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.Id)
            .Query(heroId)
        )
    )
);

var superhero = searchResponse.Documents.FirstOrDefault();
if (superhero != null)
{
    LitID.Text = superhero.Id;
    LitName.Text = superhero.name;
    LitPowers.Text = superhero.powerstats;
    LitOccupation.Text = superhero.occupation;
}
else
{
    litInfo.Text = "未找到指定英雄";
}

可选优化:统一文档ID与自定义字段

为避免混淆,可通过NEST特性将实体类的Id字段映射为Elasticsearch文档的_id:

public class esHero
{
    [PropertyName("_id")] // 标记该字段对应ES文档的_id
    public string Id { get; set; }
    public string name { get; set; }
    public string powerstats { get; set; }
    public string occupation { get; set; }
}

后续添加文档时,直接使用实体的Id作为文档_id:

POST superheroes/_doc
{
  "Id": "one",
  "name": "Superman",
  "powerstats": "Super strength, flight, invulnerability",
  "occupation": "No occupation"
}

这样查询时,传递one即可直接用Get方法获取文档,无需区分两种ID。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:17:35