【问题标题】:ElasticSearch data modeling with Mysql使用 Mysql 进行 ElasticSearch 数据建模
【发布时间】:2020-11-30 01:03:34
【问题描述】:

我正在研究弹性搜索并尝试使用 mysql 表进行建模。 例如,我有下面的 Mysql 表。

书桌

  • 身份证
  • 标题
  • 摘要
  • publisher_id

例如)书桌


标识 |标题 |摘要 | publisher_id

3 |书名A |一本关于弹性搜索的书。 | 12


作者表

  • 身份证
  • 姓名
  • 国家
  • book_id(来自 Book 表的 ID)

例如)作者表


标识 |姓名 |国家 | book_id

1 |亚历克斯 |韩国 | 3

2 |约翰 |美国 | 3


作者可能不止一个人。

发布商表

  • 身份证
  • 姓名

例如)发布者表


标识 |名称

12 |打包酒吧


在我看来,我可以像下面这样转换为弹性搜索索引。

图书索引

  • id int
  • 标题字符串
  • 抽象字符串
  • 作者 数组(来自作者索引的 ID。作者可能不止一个。)
  • publisher int(id 表单发布者索引)

作者索引

  • id int
  • 名称​​字符串
  • 国家字符串

出版商索引

  • id int
  • 名称​​字符串

我需要做的是,搜索书名和摘要并获取作者的 ID。 然后显示作者列表。 对于mysql,我会这样做。

Select * from authors where id in (select authors_id from book where match(title,abstract) against('${keyword}' IN BOOLEAN MODE))

我如何为弹性搜索做到这一点? 有没有更好的建模方法? 我也想知道怎么查询 首先从书籍索引中搜索作者 ID,然后再次使用作者的这些 ID 进行搜索?? 或任何其他解决方案???

【问题讨论】:

  • first 你应该阅读一些关于 nosql 数据库建模的文档。快速回答是您应该将所有数据放在一个索引中。查询会更容易。您可以在术语或匹配查询中进行 AND。
  • Hamid 是对的,请阅读一些关于基于文档的 noSql 的好书。在设计索引时,您需要进行范式更改。与其先考虑存储空间,不如考虑一下您需要对数据执行的查询,并针对需要保持数据冗余的查询和时间进行优化,这里绝对没问题。玩得开心!
  • @Sehun,我完全同意 hamid 和 ibexit 的观点,在这种情况下,您应该将所有数据存储在同一个索引中,在我的回答中添加了一个相关的示例小示例以使其清楚。
  • 感谢您的所有 cmets。我想错了……现在我明白了。 :)

标签: mysql database elasticsearch full-text-search search-engine


【解决方案1】:

正如其他 ES 专家指出的那样,使用 Elasticsearch(ES) 中的单个索引很容易实现这一点,我可能无法提供正确的 ES 查询,但我下面的示例为您提供了有关如何建模数据和查询一下。

索引映射

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "abstract":{
        "type" : "text"
      },
      "author" :{
        "type" : "text",
        "fielddata" : true // instead of this, you can use `keyword` field for better perf, this is just for ex
      }
    }
  }
}

索引示例文档

{
  "title" : "hello world",
  "abstract" : "hello world is common in computer programming",
  "author" : ["sehun, stackoverflow"]
}

{
  "title" : "foo bar",
  "abstract" : "foo bar is common in computer programming",
  "author" : ["opster, stackoverflow"]
}

搜索查询以搜索 titleabstract 以及作者字段上的 agg

{
  "query": {
    "multi_match": {
      "query": "common",
      "fields": [
        "title",
        "abstract"
      ]
    }
  },
  "aggs": {
    "Cities": {
      "terms": {
        "field": "author"
      }
    }
  }
}

搜索结果

hits": [
      {
        "_index": "internaledgepre",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.18232156,
        "_source": {
          "title": "foo bar",
          "abstract": "foo bar is common in computer programming",
          "author": [
            "opster, stackoverflow"
          ]
        }
      },
      {
        "_index": "internaledgepre",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.18232156,
        "_source": {
          "title": "hello world",
          "abstract": "hello world is common in computer programming",
          "author": [
            "sehun, stackoverflow"
          ]
        }
      }
    ]
  },
  "aggregations": {
    "Cities": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "stackoverflow",
          "doc_count": 2
        },
        {
          "key": "opster",
          "doc_count": 1
        },
        {
          "key": "sehun",
          "doc_count": 1
        }
      ]
    }
  }

【讨论】:

  • 感谢您的完美回答。但是,我认为我不能将所有数据都来自 MySQL。那么可以同时使用 Elastic Search 和 MySQL 吗?从 Elastic Search 中查找图书并从 MySQL 中查找作者信息。
  • @SehunPark,你可以使用mysql作为事实来源,但是为什么要从mysql中找到作者信息并在事务中添加另一个跃点
【解决方案2】:

NoSQL 不像 SQL 支持的那样支持连接。所以所有数据都应该在一个文档中进行索引。

了解 nosql 数据建模、架构、意义,并了解它与 SQL 的不同之处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-28
    • 2017-03-11
    • 2018-05-19
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 2017-04-07
    • 2016-11-27
    相关资源
    最近更新 更多