sql server全文搜索json

时间:2017-09-25 19:05:35

标签: sql-server json search

我需要在sql server中有效表示json,这样我才能执行非常快速的搜索操作。

我有什么:

要存储的json:

{"person": {
  "name": "1234",
  "age": "99",
  "parameters": {
    "param1": "1",
    "param2": "2"
  }
}}

{"person": {
  "name": "12345",
  "age": "996",
  "parameters": {
    "param1": "1",
    "param5": "5",
    "param7": "7"
  }
}}

参数部分最多可包含60个不同参数中的20个。 我只需要使用一些参数来查找人。如果有人有12我可以在搜索查询中使用0-12个参数。搜索查询中始终提供姓名和年龄,每个人都有。 我桌上有大约30米的jsons。

是否可以使用sql server而不使用nosql / solr / elastic?

2 个答案:

答案 0 :(得分:0)

通过使用ADD col1 AS JSON_VALUE(data,'$.person.parameters.param1') 添加计算列然后索引这些计算列,可以获得sql server上的高搜索性能。

E.g。 Index JSON data

(如果我们需要提供特定的代码示例,请提供一个关于如何将json存储在sql表中的示例。)

答案 1 :(得分:0)

让我们来看一下并创建一个表,该表会将json存储在列中,并将要搜索的所有参数存储在虚拟计算列中:

CREATE TABLE [dbo].[JsonTest](
    [_id] [bigint] IDENTITY(1,1) NOT NULL,
    [Json] [nvarchar](max) NOT NULL,
    [Parameter1]  AS (CONVERT([varchar](20),json_value([Json],'$.person.parameters.param1'))),
    [Parameter2]  AS (CONVERT([varchar](20),json_value([Json],'$.person.parameters.param2'))),
CONSTRAINT [PK_JsonTest] PRIMARY KEY CLUSTERED 
(
    [_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


ALTER TABLE [dbo].[JsonTest]  WITH CHECK ADD  CONSTRAINT [CK_JsonTest_Json] CHECK  ((isjson([Json])=(1)))

然后插入您提供的两个示例:

INSERT INTO [JsonTest] (Json) VALUES ('{"person": {
  "name": "1234",
  "age": "99",
  "parameters": {
    "param1": "1",
    "param2": "2"
  }
}}')

INSERT INTO [JsonTest] (Json) VALUES ('{"person": {
  "name": "12345",
  "age": "996",
  "parameters": {
    "param1": "1",
    "param5": "5",
    "param7": "7"
  }
}}')

现在查询表时:

SELECT TOP 100 * FROM [dbo].[JsonTest]

然后我们得到一个结果:

enter image description here

请注意,当没有此类参数时,计算列也将起作用。

下一步是在计算列上创建索引:

CREATE NONCLUSTERED INDEX [IX_JsonTest_Parameter1] ON [dbo].[JsonTest]
(
    [Parameter1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

CREATE NONCLUSTERED INDEX [IX_JsonTest_Parameter2] ON [dbo].[JsonTest]
(
    [Parameter2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

现在您终于可以非常快速地查询表了:

SELECT [Json], Parameter1, Parameter2
FROM [dbo].[JsonTest]
WITH (INDEX(IX_JsonTest_Parameter1),INDEX(IX_JsonTest_Parameter2))
WHERE Parameter1 = 1 and Parameter2 = 2

此方法在不到1秒的时间内查询包含200万条记录的表。请记住,我们只保留json值。

如果要使用全文本搜索,则必须先启用它。此处描述了所有内容:Cannot use a CONTAINS or FREETEXT predicate on table or indexed view because it is not full-text indexed

现在查询看起来类似于:

SELECT [Json]
FROM JsonTest
Where Contains(Json,'Near((param1,1), MAX, True)')