在数据库中查找相似的文档/记录

时间:2019-01-12 21:43:16

标签: database mongodb elasticsearch nosql

所以我目前在mongodb中存储了大量记录,每条记录看起来都是这样的:

{
    "_id" : ObjectId("5c38d267b87d0a05d8cd4dc2"),
    "tech" : "NodeJs",
    "packagename" : "package-name",
    "packageversion" : "0.0.1",
    "total_loc" : 474,
    "total_files" : 7,
    "tecloc" : {
        "JavaScript" : 316,
        "Markdown" : 116,
        "JSON" : 42
    }
}

我想做的是根据例如具有total_loc数量大约(+/- 10%)的记录或使用某些相同的技术(tecloc)查找类似的数据记录。

我可以通过对mongodb的查询以某种方式做到这一点,还是有一种技术更适合我想做的事情?我可以重新生成数据并将其存储在例如Elastic或graph-db中。

谢谢:)

1 个答案:

答案 0 :(得分:1)

解决此问题的一种可能是使用Elasticsearch。我并不是说这是您唯一的解决方案。

从高层次上讲,您需要设置Elasticsearch并为数据建立索引。有多种实现方式:mongo-connector,Logstash和JDBC input plugin,甚至只是从MongoDB转储数据并手动进行处理。这项工作没有限制。

我最初建议的区别是通过将{替换为[,并为代码行添加一些其他字段来使字段 tecloc -多值字段:

   {
      "tech": "NodeJs",
      "packagename": "package-name",
      "packageversion": "0.0.1",
      "total_loc": 474,
      "total_files": 7,
      "tecloc": [
        {
          "name": "JavaScript",
          "loc": 316
        },
        {
          "name": "Markdown",
          "loc": 116
        },
        {
          "name": "JSON",
          "loc": 42
        }
      ]
    }

该数据模型非常琐碎,显然有一些限制,但是您已经可以从中开始了解它如何适合您的其他用例。稍后,您应该发现nested类型是更正确地模拟数据的一种可能性。

关于确切的搜索方案-您可以使用类似的查询来搜索这类文档:

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "tecloc.name.keyword": {
              "value": "Java"
            }
          }
        },
        {
          "term": {
            "tecloc.name.keyword": {
              "value": "Markdown"
            }
          }
        }
      ],
      "must": [
        {"range": {
          "total_loc": {
            "gte": 426,
            "lte": 521
          }
        }}
      ]
    }
  }
}

不幸的是,不支持+ -10%的语法,因此应在客户端上进行计算。

另一方面,我指定我们要搜索应该具有Java或Markdown的文档,这些文档也将返回示例文档。在这种情况下,如果我同时具有Java Markdown的文档,则该文档的得分会更高。