json对象数组格式(json数组和json对象区别)
在elasticsearch中,使用json结构来存储数据,一个key/value对是json的一个字段,而value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个json文档都内在地具有层次结构。复合数据类型是指数组类型,对象类型和嵌套类型,各个类型的特点分别是:数组字段是指一个字段有多个值,每个值都是该数组字段的一个元素;元素的类型可以是基础类型,也可以是文档类型;对象类型是指字段的值是一个json文档;嵌套字段是指对象类型的一个特殊版本,elasticsearch引擎在内部把嵌套字段索引成单个文档。如果在嵌套字段中定义对象数组,那么对象数组中的每个元素(文档)都被索引成单个文档,每个文档都能被独立地查询。
一,对象类型
json文档是有层次结构的,一个文档可能包含其他文档,如果一个文档包含其他文档,那么该文档值是对象类型,其数据类型是对象,elasticsearch默认把文档的属性type设置为object,即”type”:”object”。
例如,在创建索引映时,定义name字段为对象类型,不需要显式定义type属性值,其默认值是object:
"manager":{
"properties":{
"age":{ "type":"integer"},
"name":{
"properties":{
"first":{"type":"string"},
"last":{ "type":"string"}
}
}
}
}
默认情况下,上述文档类型被索引为以点号命名的数据结构,把层次结构展开之后,数据结构是由扁平的key/value对构成:
{
"manager.age": 30,
"manager.name.first": "john",
"manager.name.last": "smith"
}
二,开箱即用的数组类型
在elasticsearch中,没有专门的数组(array)数据类型,但是,在默认情况下,任意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组类型的各个元素值的数据类型必须相同。在elasticsearch中,数组是开箱即用的(out of box),不需要进行任何配置,就可以直接使用。
1,数组类型
在同一个数组中,数组元素的数据类型是相同的,elasticsearch不支持元素为多个数据类型:[ 10, “some string” ],常用的数组类型是:字符数组: [ “one”, “two” ]整数数组: productid:[ 1, 2 ]对象(文档)数组: “user”:[ { “name”: “mary”, “age”: 12 }, { “name”: “john”, “age”: 10 }],elasticsearch内部把对象数组展开为 {“user.name”: [“mary”, “john”], “user.age”: [12,10]}
对于文档数组,每个元素都是结构相同的文档,文档之间都不是独立的,在文档数组中,不能独立于其他文档而去查询单个文档,这是因为,一个文档的内部字段之间的关联被移除,各个文档共同构成对象数组。
对整数数组进行查询,例如,使用多词条(terms)查询类型,查询productid为1和2的文档:
{
"query":{
"terms":{
"productid":[ 1, 2 ]
}
}
}
2,对象数组
通过put动词,自动创建索引和文档类型,在文档中创建对象数组:
put my_index/my_type/1
{
"group" : "fans",
"user" : [
{
"first" : "john",
"last" : "smith"
},
{
"first" : "alice",
"last" : "white"
}
]
}
elasticsearch引擎内部把对象数组展开成扁平的数据结构,把上例的文档类型的数据结构展开之后,文档数据类似于:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
字段 user.first 和 user.last 被展开成数组字段,但是,这样展开之后,单个文档内部的字段之间的关联就会丢失,在该例中,展开的文档数据丢失first和last字段之间的关联,比如,alice 和 white 的关联就丢失了。
三,嵌套数据类型
嵌套数据类型是对象数据类型的特殊版本,它允许对象数组中的各个对象被索引,数组中的各个对象之间保持独立,能够对每一个文档进行单独查询,这就意味着,嵌套数据类型保留文档的内部之间的关联,elasticsearch引擎内部使用不同的方式处理嵌套数据类型和对象数组的方式,对于嵌套数据类型,elasticsearch把数组中的每一个嵌套文档(nested document)索引为单个文档,这些文档是隐藏(hidden)的,文档之间是相互独立的,但是,保留文档的内部字段之间的关联,使用嵌套查询(nested query)能够独立于其他文档而去查询单个文档。在创建嵌套数据类型的字段时,需要设置字段的type属性为nested。
1,在索引映射中创建嵌套字段
设置user字段为嵌套数据类型,由于每个字段默认都可以是数组类型,因此,嵌套字段也可以是对象数组。
"mappings":{
"my_type":{
"properties":{
"group":{ "type":"string"},
"user":{
"type":"nested",
"properties":{
"first":{ "type":"string"},
"second":{ "type":"string"}
}
}
}
}
}
2,为嵌套字段赋值
为嵌套字段赋予多个值,那么elasticsearch自动把字段值转换为数组类型。
put my_index/my_type/1
{
"group" : "fans",
"user" : [
{ "first" : "john", "last" : "smith"},
{ "first" : "alice", "last" : "white"}
]
}
在elasticsearch内部,嵌套的文档(nested documents)被索引为很多独立的隐藏文档(separate documents),这些隐藏文档只能通过嵌套查询(nested query)访问。每一个嵌套的文档都是嵌套字段(文档数组)的一个元素。嵌套文档的内部字段之间的关联被elasticsearch引擎保留,而嵌套文档之间是相互独立的。在该例中,elasticsearch引起保留alice和white之间的关联,而john和white之间是没有任何关联的。
默认情况下,每个索引最多创建50个嵌套文档,可以通过索引设置选项:index.mapping.nested_fields.limit 修改默认的限制。
indexing a document with 100 nested fields actually indexes 101 documents as each nested document is indexed as a separate document.
四,嵌套查询
嵌套查询用于查询嵌套对象,执行嵌套查询执行的条件是:嵌套对象被索引为单个文档,查询作用在根文档(root parent)上。嵌套查询由关键字“nested”指定:
"nested" : {
"path" : "obj1",
"query" : {...}
1,必须赋值的参数:path参数:指定嵌套字段的文档路径,根路径是顶层的文档,通过点号“.”来指定嵌套文档的路径;query参数:在匹配路径(参数path)的嵌套文档上执行查询,query参数指定对嵌套文档执行的查询条件。
2,使用嵌套查询访问嵌套文档
get my_index/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "alice" }},
{ "match": { "user.last": "white" }}
]
}
}
}
}
}
五,使用c#索引数组类型
1,创建elasticsearch的索引映射
{
"settings":{
"number_of_shards":5,
"number_of_replicas":0
},
"mappings":{
"events":{
"dynamic":"false",
"properties":{
"eventid":{
"type":"long",
"store":true,
"index":"not_analyzed"
},
"eventname":{
"type":"string",
"store":true,
"index":"analyzed",
"fields":{
"raw":{
"type":"string",
"store":true,
"index":"not_analyzed"
}
}
},
"topics":{
"type":"integer",
"store":true,
"index":"analyzed"
}
}
}
}
}
对于topics字段,类型是integer,赋予其一组整数值[1,2,3],那么该字段就能存储数组。
"topics":{
"type":"integer",
"store":true,
"index":"analyzed"
}
2,创建数据模型(data model)
为数组字段定义为list类型,每个列表项的数据类型是int。
public class eventbase
{
public long eventid { get; set; }
}
public class ebrieevents:eventbase
{
public string eventname { get; set; }
public list<int> topics { get; set; }
}
3,为字段赋值
为list字段topics赋值,调用nest对该文档进行索引
ebrieevents pb = new ebrieevents();
//topics list
list<string> strtopics = tablerow["topics"].tostring().trimend(',').split(',').tolist();
list<int> topics = new list<int>();
foreach(string str in strtopics)
{
topics.add(int.parse(str));
}
pb.topics = topics;
4,查询数组字段
{
"query":{
"terms":{
"topics":[1001,487]
}
}
}
上一篇: 来,来,来,一起抖音,错~了~ 是抖胸!
下一篇: 无敌逗比的动物萌图,泰迪脸亮了
推荐阅读
-
在PHP语言中使用JSON和将json还原成数组
-
JavaScript数组、json对象、eval()函数用法实例分析
-
js定义对象或数组直接量时各浏览器对多余逗号的处理(json)_javascript技巧
-
jQuery asp.net 用json格式返回自定义对象_jquery
-
js/jquery解析json和数组格式的方法详解_javascript技巧
-
PHP如何将JSON转换成数组/对象
-
FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换操作
-
Android解析json数组对象的方法及Apply和数组的三个技巧
-
Android解析json数组对象的方法及Apply和数组的三个技巧
-
C#实现JSON和对象之间互相转换功能示例