elasticsearch - 如何在ElasticSearch中反规范化层次结构?

标签 elasticsearch hierarchical-data denormalization

我是ElasticSearch的新手,我有一棵树,它描述了某个文档的路径(不是真实的文件系统路径,只是将文章,图像和文档归类为一个简单的文本字段)。每个路径条目都有一个类型,例如:Group NameAssembly name甚至Unknown。例如,可以在查询中使用这些类型以跳过路径中的某些条目。

我的源数据存储在SQL Server中,该架构如下所示:
enter image description here

通过将Tree.Id连接到Tree.ParentId来构建树,但是每个节点必须具有一个类型。文档连接到树中的叶子。

我不担心在SQL Server中查询结构,但是我应该找到一种最佳方法来对非规范化并在Elastic中搜索它们。如果我弄平路径并列出文档的“描述符”列表,则可以将每个“文档”条目存储为 flex 文档。

{
  "path": "NodeNameRoot/NodeNameLevel_1/NodeNameLevel_2/NodeNameLevel_3/NodeNameLevel_4",
  "descriptors": [
    {
      "name": "NodeNameRoot",
      "type": "type1"
    },
    {
      "name": "NodeNameLevel_1",
      "type": "type1"
    },
    {
      "name": "NodeNameLevel_2",
      "type": "type2"
    },
    {
      "name": "NodeNameLevel_3",
      "type": "type2"
    },
    {
      "name": "NodeNameLevel_4",
      "type": "type3"
    }
  ],
  "document": {
    ...
  }
}

我可以在ElasticSearch中查询这样的结构吗?还是应该以其他方式对路径进行非规范化?

我的主要问题:

可以根据类型或文本值查询它们(例如正则表达式匹配)。例如:给我所有的type2-> type3路径(实际上将type1排除在外),其中路径包含X

是否可以根据级别进行查询?就像我想要的路径,其中有4个描述符。

我可以使用内置功能进行搜索还是需要编写扩展名?

编辑
基于G Quintana的答案,我做了这样的索引:
curl -X PUT \
  http://localhost:9200/test \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{
  "mappings": {
    "path": {
      "properties": {
        "names": {
          "type": "text",
          "fields": {
            "raw": {
              "type": "keyword"
            },
            "tokens": {
              "type": "text",
              "analyzer": "pathname_analyzer"
            },
            "depth": {
              "type": "token_count",
              "analyzer": "pathname_analyzer"
            }
          }
        },
        "types": {
          "type": "text",
          "fields": {
            "raw": {
                "type": "keyword"
            },
            "tokens": {
                "type": "text",
                "analyzer": "pathname_analyzer"
            }
          }
        }
      }
    }
  },
  "settings": {
    "analysis": {
      "analyzer": {
        "pathname_analyzer": {
          "type": "pattern",
          "pattern": "#->>",
          "lowercase": true
        }
      }
    }
  }
}'

并可以这样查询深度:
curl -X POST \
  http://localhost:9200/test/path/_search \
  -H 'content-type: application/json' \
  -d '{
    "query": {
        "bool": {
            "should": [
                {"match": { "names.depth": 5 }}
            ]
        }
    }
}'

哪个返回正确的结果。我会再测试一点。

最佳答案

首先,您应该确定所有查询模式,以设计如何索引数据。

从您给出的示例中,我将为以下格式的文档建立索引:

{
  "path": "NodeNameRoot/NodeNameLevel_1/NodeNameLevel_2/NodeNameLevel_3/NodeNameLevel_4",
  "types: "type1/type1/type2/type2/type3",
  "document": {
    ...
  }
}

编制索引之前,必须配置映射和分析:
  • 字段path:
  • 使用text类型+基于pattern analyzer的分析器来分割/字符
  • 使用 token_count 类型+同一个分析器来计算路径深度。创建一个multi field(path.depth)
  • 字段types
  • 使用text类型+基于pattern analyzer的分析器来分割/字符

  • 配置索引映射和分析以拆分pathtypes字段以及,使用a或a
  • 给我所有的type2-> type3路径,在match_phrase字段
  • 上使用types查询
    路径包含X的
  • match字段
  • 上使用path查询
    那里有4个描述符的
  • term子字段
  • 上使用path.depth查询

    您的描述符字段并不有趣。
    对于某些用例,Path tokenizer可能很有趣。
    您可以使用multi-fields在同一字段上应用多个分析器,然后查询是否有子字段。

    关于elasticsearch - 如何在ElasticSearch中反规范化层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46790343/

    相关文章:

    sorting - Elasticsearch 排序不起作用

    ruby-on-rails - 如何使用searchkick设置word_middle区分大小写的搜索?

    elasticsearch - 限制 Elastic Search 返回的结果数量

    sql - 我应该使用平面表还是规范化数据库?

    elasticsearch - 我如何使用Lucene查询语法在Elastic Search中进行嵌套字段查询

    asp.net-mvc-3 - MVC3 导航和面包屑 - 数据驱动

    sql - 如何从平面表中提取层次结构?

    mysql - 如何创建MySQL分层递归查询

    mysql - SQL 数据库中的非规范化或规范化(继承数据)

    database - 何时存储预先计算的值与在检索它们时计算它们?