【问题标题】:can not search elasticsearch based on document property values无法根据文档属性值搜索弹性搜索
【发布时间】:2016-04-20 10:51:20
【问题描述】:

我在 elasticsearch 中保存了很多产品类型的文档,但无法按文档属性值进行搜索,需要帮助。

//Product Class
public Guid productID { get; set; }
public string productName { get; set; }
public Guid productTypeID { get; set; }
public List<Guid> categoryIds {get; set; }

我正在尝试这样搜索:

//Search function
var esconn = Yaziylabir.Bukalemun.DataObjects.ElasticSearchConnectionManager.GetClient();
QueryContainer q = null;
if (!ProductType.HasValue || (ProductType.HasValue && ProductType.Value == B2CVariables.PRODUCTTYPE_PRODUCT))
{
    q = Query<ProductModel>.Term(t => t.ProductTypeID, B2CVariables.PRODUCTTYPE_PRODUCT);
}
if (Category != null)
{
    //catListZ is also List<Guid>
    q &= Query<ProductModel>.Terms(u=>u.Field(z=>z.CategoryIDs).Terms<Guid>(catListZ));
}
// as a bonus I also have keyword search
if (!string.IsNullOrEmpty(Keyword))
{
    q &= Query<ProductModel>.QueryString(t => t.Query(Keyword));
}

//do search
var pp = new SearchRequest(Yaziylabir.Bukalemun.DataObjects.ElasticSearchConnectionManager.DefaultIndex, "product");
pp.Query = q;
pp.Size = PageSize;
var res = esconn.Search<ProductModel>(pp);
rtnVal = res.Documents.ToList();

现在,我尝试了这些组合(仅 producttypeID、仅 categoryID、仅关键字等)并观察 fiddler 发生了什么。

没有返回结果,也没有引发错误。只有 0 次命中。请求正文似乎也可以。

当我检查存储在该索引中的文档时,它们就在那里,并且它们具有所需的值并且应该在结果中返回。

这里有什么问题?你有什么想法?请在这里帮助我。作为无法正确搜索数据库的人,我感到很惭愧。

编辑: 搜索的正文:

{"size":12,"query":{"term":{"productTypeID":{"value":"cae344cf-8cfa-4960-8387-8ee89899c53f"}}}}

示例文档:

{
  "productID": "5687b8ac-c3fe-4f1a-9643-08b0bf6cede8",
  "productName": "7011 Yelek",
  "productCode": "701102Y001  ",
  "currency": {
    "currencyID": 1,
    "sign": "TL",
    "rate": 0
  },
  "normalPrice": 170,
  "currentPrice": 84.9,
  "isDiscounted": true,
  "taxRate": 8,
  "productTypeID": "cae344cf-8cfa-4960-8387-8ee89899c53f",
  "defaultImagePath": "/contents/images/productimages/75681ee4-19b3-4c7d-a24b-b3566085a980.jpg",
  "totalStockCount": 8,
  "totalStockRecordCount": 4,
  "isInStock": true,
  "statusID": "9ad17471-2ff2-4eb0-9cb0-4b86922263ea",
  "categoryIDs": [
    "a8c83f54-b784-4866-89c3-cabc641490d5",
    "9d5a9ab7-8edb-4d5a-800b-c48bf6575d78"
  ]
}

我没有包含所有属性,因为它会使文档变得很长。
这是映射:

{
  "mappings": {
    "product": {
      "properties": {
        "categoryIDs": {
          "type": "string"
        },
        "currentPrice": {
          "type": "double"
        },
        "isDiscounted": {
          "type": "boolean"
        },
        "isInStock": {
          "type": "boolean"
        },
        "normalPrice": {
          "type": "double"
        },
        "productCode": {
          "type": "string"
        },
        "productID": {
          "type": "string"
        },
        "productName": {
          "type": "string"
        },
        "productTypeID": {
          "type": "string"
        },
        "statusID": {
          "type": "string"
        },
        "taxRate": {
          "type": "double"
        },
        "totalStockCount": {
          "type": "long"
        },
        "totalStockRecordCount": {
          "type": "long"
        }
      }
    }
  }
}

【问题讨论】:

  • 您能否举例说明您拥有的文档以及您正在搜索的term,您认为它应该被退回?此外,这将有助于查看索引的映射。
  • 正如我们所说,我重新索引数据,这需要一些时间,因为我是一个不使用别名的白痴。索引完成后,我将使用这些详细信息编辑我的问题。顺便说一句,我通过这种方式用更深的嵌套用法重建我的代码,我们将看看我是否理解何时标记嵌套的属性:-)
  • @AndreiStefan 我用示例产品文档和搜索正文更新了问题,而不是只提供术语。
  • 你能显示productTypeID字段的映射吗?
  • 顺便说一句,我没有手动创建映射,elasticsearch 是从我猜的类结构自动创建的。我删除了大量属性以解决问题。如果我提供的映射和文档没有相同的结构,那是因为我。我有嵌套的属性,但我也看不到这些属性的嵌套类型。我索引错误吗?如果你愿意,我也可以提供索引代码。

标签: c# elasticsearch nest


【解决方案1】:

我怀疑 productTypeID 字段正在使用默认分析器 - standard - 或任何其他将其拆分到错误位置的分析器。您需要将productTypeID 设为index: not_analyzed 或使用keyword 之类的内容进行分析。并且需要手动创建映射,否则无法按照自己的方式进行。

这个想法是 ES 默认标记您的 productTypeID 值并将它们拆分为 -,因此在索引中您将拥有标记而不是整个值。相反,您需要保持该值不变,以便 term 完全匹配它。

例如,为了不弄乱您之前的映射,您可以添加fields 来定义一个子字段,即not_analyzed

    "productTypeID": {
      "type": "string",
      "fields": {
        "raw": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }

您的查询需要稍作更改:{"size":12,"query":{"term":{"productTypeID.raw":{"value":"cae344cf-8cfa-4960-8387-8ee89899c53f"}}}}

为了完整起见,这是手动创建映射的完整命令。您可以在索引仍然“活动”时执行此操作,但您仍然需要重新索引文档:

curl -XPUT "http://localhost:9200/your_index" -d'
{
  "mappings": {
    "product": {
      "properties": {
        "categoryIDs": {
          "type": "string"
        },
        "currentPrice": {
          "type": "double"
        },
        "isDiscounted": {
          "type": "boolean"
        },
        "isInStock": {
          "type": "boolean"
        },
        "normalPrice": {
          "type": "double"
        },
        "productCode": {
          "type": "string"
        },
        "productID": {
          "type": "string"
        },
        "productName": {
          "type": "string"
        },
        "productTypeID": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "statusID": {
          "type": "string"
        },
        "taxRate": {
          "type": "double"
        },
        "totalStockCount": {
          "type": "long"
        },
        "totalStockRecordCount": {
          "type": "long"
        }
      }
    }
  }
}'

【讨论】:

  • 感谢您的回答安德烈。这是我学习的测试环境。所以我可以重新索引。如果有更简单的解决方案,我想听听。因为我将按照我学习的方式在整个代码中实现解决方案。顺便说一句,我使用的是 c#,所以我使用的是nest。我找不到分析等属性。还有一个问题:我不能使用自动映射来提供适当的属性吗?
  • 那是一个更长的故事。这是关于您在搜索时需要什么,并且根据此,您可以考虑如何处理映射。两者一起工作,你不能只是索引然后在搜索中挣扎,因为它可能不起作用。
  • elastic.co/guide/en/elasticsearch/client/net-api/1.x/…: public string Name { get; set; } [ElasticProperty(OmitNorms = true, Index = FieldIndexOption.not_analyzed)] 快速谷歌搜索后。
  • ElasticProperty 属性是我在当前版本的 Nest 中找不到的。这实际上是我这些天在 stackoverflow 上花费大量时间的最大原因之一 :-) 我找到了另一个要使用的属性而不是 ElasticProperty,但我不确定这是否是我正在寻找的:TokenCount。我尝试像 [Nest.TokenCount(Index = Nest.NonStringIndexOption.NotAnalyzed)] 一样使用它,但我再次不确定它是否是,如果是,单独使用 NotAnalyzed 是否足够,或者我也应该设置另一个属性。
猜你喜欢
  • 2022-08-12
  • 2015-12-18
  • 2015-06-01
  • 2016-02-27
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多