我需要在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?
答案 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]
然后我们得到一个结果:
请注意,当没有此类参数时,计算列也将起作用。
下一步是在计算列上创建索引:
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)')