2012-07-19 90 views
2

我开始研究elasticsearch,我想知道这个操作是否可以完成它:(我做了一些搜索,但我承认我不知道该找什么)。elasticsearch的多领域操作

我有这样的两个联系人数据:

{ 
    "id"  : "id1", 
    "name" : "Roger", 
    "phone1" : "123", 
    "phone2" : "", 
    "phone3" : "980" 
} 

{ 
    "id"  : "id2", 
    "name" : "Lucas", 
    "phone1" : "789", 
    "phone2" : "123", 
    "phone3" : "" 
} 

!我想知道,如果elasticsearch可以帮我找到的电话号码复制,即使它们在不同的手机领域(“123”这里是存在于记录)。 我已经看到我可以在多个字段中搜索一个字符串,所以如果我搜索123,我可以得到这两个记录作为结果。不过,我想问题,它可以返回我像这样的请求的能力:

{ 
    "phones" : { 
    "123" : ["id1", "id2"], 
    "980" : ["id1"], 
    "789" : ["id2"] 
    } 
} 

甚至这将是有益的(与多个触点数量):

{ 
    "phones" : { 
    "123" : 2, 
    "980" : 1, 
    "789" : 1 
    } 
} 

任何想法如果这是可能的?如果可以的话,那将会很棒。

回答

4

我同意DrTech的建议来更改您的数据结构。但是,如果你因为某些原因,宁愿离开它是,你可以使用多领域达到同样的效果而言一面:

curl "localhost:9200/phonefacet/_search?pretty=true&search_type=count" -d '{ 
    "query" : { 
     "match_all" : { } 
    }, 
    "facets" : { 
     "tag" : { 
      "terms" : { 
       "fields" : ["phone1", "phone2", "phone3"], 
       "size" : 10 
      } 
     } 
    } 
}' 

结果是这样的:

{ 
    "took" : 1, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 2, 
    "max_score" : 0.0, 
    "hits" : [ ] 
    }, 
    "facets" : { 
    "tag" : { 
     "_type" : "terms", 
     "missing" : 2, 
     "total" : 4, 
     "other" : 0, 
     "terms" : [ { 
     "term" : "123", 
     "count" : 2 
     }, { 
     "term" : "980", 
     "count" : 1 
     }, { 
     "term" : "789", 
     "count" : 1 
     } ] 
    } 
    } 
} 
+0

我不知道你能做到这一点!太好了! – DrTech 2012-07-20 08:29:39

+0

太好了!既然你们都建议改变模式,那么你的建议有什么缺点/性能问题?我宁愿保留字段的标签(实际上更像modile_phone,home_phone等...) – Schmurfy 2012-07-20 11:37:04

+0

我只是在想,从架构设计的角度来看,如果您使用手机字段作为数组,它可能是最好在elasticsearch中将其表示为一个数组。我无法想象您的架构中与DrTech提出的任何重大性能问题相比。在一种情况下,elasticsearch必须读取3个字段并合并结果,并在另一个字段中大小等于3个字段。与阅读和保存存储器中的字段值相比,合并不应该很昂贵。 – imotov 2012-07-20 13:57:55

1

你可以到那里使用terms facet,但你必须改变你的数据结构包含在一个单一领域的所有电话号码:

创建索引:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1' 

指数的数据:

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d ' 
{ 
    "name" : "Roger", 
    "id" : "id1", 
    "phone" : [ 
     "123", 
     "980" 
    ] 
} 
' 

curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1' -d ' 
{ 
    "name" : "Lucas", 
    "id" : "id2", 
    "phone" : [ 
     "789", 
     "123" 
    ] 
} 
' 

搜索上的所有字段,返回条款的计数phone

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1' -d ' 
{ 
    "facets" : { 
     "phone" : { 
     "terms" : { 
      "field" : "phone" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "name" : "Roger", 
#    "id" : "id1", 
#    "phone" : [ 
#     "123", 
#     "980" 
#    ] 
#    }, 
#    "_score" : 1, 
#    "_index" : "test", 
#    "_id" : "StaJK9A5Tc6AR7zXsEKmGA", 
#    "_type" : "test" 
#   }, 
#   { 
#    "_source" : { 
#    "name" : "Lucas", 
#    "id" : "id2", 
#    "phone" : [ 
#     "789", 
#     "123" 
#    ] 
#    }, 
#    "_score" : 1, 
#    "_index" : "test", 
#    "_id" : "x8w39F-DR9SZOQoHpJw2FQ", 
#    "_type" : "test" 
#   } 
#  ], 
#  "max_score" : 1, 
#  "total" : 2 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "facets" : { 
#  "phone" : { 
#   "other" : 0, 
#   "terms" : [ 
#    { 
#    "count" : 2, 
#    "term" : "123" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "980" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "789" 
#    } 
#   ], 
#   "missing" : 0, 
#   "_type" : "terms", 
#   "total" : 4 
#  } 
# }, 
# "took" : 5 
# } 
+0

谢谢,这是我的想法,但我很好奇,如果有另一种方式。改变存储数据的模式目前不是问题,所以我会按照你的建议。 – Schmurfy 2012-07-19 15:59:15