如何匹配一个数组值通过它的键值在一个键值中弹性搜索数组? [英] how to match an array value by it's key in a key value pair elasticsearch array?
问题描述
我有一个数组键值
对。是否可以确切匹配键匹配值
&然后检查它的值
的范围值?
示例:在下面的doc oracle_props
是一个名称,值对的数组。我需要检查它是否有oracle_cursors
键,然后检查它是否小于1000。
GET / eg / message / _percolate
{
doc:{
client:{
name:Athena ,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props :[
{
@name:open_cursors,
@value:4000
},
{
@name :USER_ROLE_PRIVS_COUNT,
@value:1
},
{
@name:CREATE_PERMISSION,
@value:Y
}
]
}
}
}
}
以下是我的渗透者。
我还需要检查以下内容o它返回 3
作为我的结果
- client.name必须Athena
- client.db。@ type必须是Oracle,那么只需继续查看
- 客户端。 db.oracle_props。@ name字段未找到
- 检查是否有oracle_cursors键,然后检查其值是否为1000
1& 2和操作,3或4中的任何一个满足它应该导致 3
。我需要帮助点4,下面是我的查询。另外请提示是否有更好的方法。
PUT /eg/.percolator/3
{
query:{
filtered:{
filter:{
or:[
{
missing:{
field:client.db.oracle_props。@ name
}
}
]
},
查询:{
bool:{
must:[
{
match:{
client.name:Athena
}
} ,
{
match:{
client.db。@ type:Oracle
}
}
]
}
}
}
}
}
更新
可以吗如下所示
{
match:{
client.db.oracle_props [name = 'open_cursors']。value:4000
}
}
更多尝试
我遵循 elasticsearch嵌套查询,并将映射更改为 nestedtype 通过重新索引。任何人都可以找到问题,为什么我得到嵌套:NullPointerException;
?
PUT /eg/.percolator/3
{
嵌套:{
path:client.db.oracle_props,
score_mode:avg
query:{
bool:{
must:[
{
match:{client.db.oracle_props。@ name :open_cursors}
},
{
range:{client.db.oracle_props。@ value:{lt:4000}}
}
]
}
}
}
}
映射更改
...
属性:{
@type :{
type:string
},
oracle_props:{
type:nested,
es:{
@name:{
type:string
},
@value:{
type长
}
}
}
}
...
让我们进一步了解:
- 嵌套路径错误,
oracle_props
是您的示例文档中的db
的子项,但不在映射中,直接作为您的根的子代。 - 您将映射
oracle_props。@ value
作为long
,但在CREATE_PERMISSION
嵌套文档 $ b $之间分配文本 - 您查询
范围<4000>
,其中不包括 4000,lte
适合你
Y
b 我没有得到你对missi的要求为了让你走向正确的道路,我必须简化一下(因为我无法按照你的所有的困惑)问题,抱歉)
我也不会渗透,并将所有内容重新命名为twitter / tweet,因为我更容易从我的示例中复制。 p>
1)创建空索引twitter
curl -XDELETE'http :// localhost:9200 / twitter /'
curl -XPUT'http:// localhost:9200 / twitter /'
2)为实际的tweet创建geo_point映射
curl -XPUT'http: / localhost:9200 / twitter / tweet / _mapping'-d'
{
tweet:{
properties:{
db:{
type:object,
properties:{
@type:{
type:string
},
oracle_props :{
type:nested,
properties:{
@name:{
type:string
},
@value:{
type:string
}
}
}
}
}
}
}
}'
3)让我们检查映射是否设置
curl -XGET'http:// localhost:9200 / twitter / tweet / _mapping?pretty = true'
$发布一些推文,嵌套数据 code> curl -XPUT'http:// localhost:9200 / twitter / tweet / 1'-d'{
name:Athena,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4.0 64位,
oracle_props:[
{
@name:open_cursors,
@value:4000
},
{
@名称:USER_ROLE_PRIVS_COUNT,
@value:1
},
{
@name:CREATE_PERMISSION,
@value Y
}
]
}
}'
5)仅嵌套查询
curl -XGET localhost:9200 / twitter / tweet / _search -d'{
query:{
nested:{
path:db.oracle_props,
score_mode:avg,
query {
bool:{
must:[
{
term:{
db.oracle_props。@ name:open_cursors
}
},
{
range:{
db.oracle_props。@ value:{
lte:4000
}
}
}
]
}
}
}
}
}';
6)查询雅典娜和甲骨文
curl -XGET localhost:9200 / twitter / tweet / _search -d'{
query:{
bool:{
must:[
{
match:{tweet.name:Athena}
},
{
match:{ tweet.db。@ type:Oracle}
}
]
}
}
}'
7)组合前两个查询
curl -XGET localhost:9200 / twitter / tweet / _search -d'{
query:{
bool:{
must:[
{
match:{tweet.name:Athena}
},
{
match:{tweet.db。@ type:Oracle}
},
{
嵌套:{
path:db.oracle_props,
score_mode:avg,
查询:{
bool:{
:[
{
term:{
db.oracle_props。@ name:open_cursors
}
},
{
范围:{
db.oracle_props。@ value:{
lte:4000
}
}
}
]
}
}
}
}
]
}
}
}'
结果为
{
take:2,
timed_out:false,
_shards:{
total:5,
successful:5,
failed:0
}
hits:{
total:1,
max_score:2.462332,
hits:[
{
_ $$$$$$$$$$$$$$
name:Athena,
version:1,
db:{
@type:Oracle数据库10g企业版版本10.2.0.4 .0 64bit,
oracle_props:[
{
@名称:open_cursors,
@value:4000
},
{
@name:USER_ROLE_PRIVS_COUNT,
@value 1
},
{
@name:CREATE_PERMISSION,
@value:Y
}
]
}
}
}
]
}
}
I have an array of key value
pairs. Is it possible to exact match value of key
& then do a check on it's value
's range value?
Example: In below doc oracle_props
is an array with name, value pairs. I need to check if it has "oracle_cursors"
key and then check if it's value is less than 1000.
GET /eg/message/_percolate
{
"doc": {
"client": {
"name": "Athena",
"version": 1,
"db": {
"@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
"oracle_props": [
{
"@name": "open_cursors",
"@value": 4000
},
{
"@name": "USER_ROLE_PRIVS_COUNT",
"@value": 1
},
{
"@name": "CREATE_PERMISSION",
"@value": "Y"
}
]
}
}
}
}
Below is my percolator.
I also need to check the following so that it gives back 3
as my result
- "client.name" must be "Athena"
- "client.db.@type" must be "Oracle" then only go ahead and check below points
- "client.db.oracle_props.@name" field is not found
- check if it has "oracle_cursors" key and then check if it's value is < 1000
1 & 2 are and operations and any of 3 or 4 satisfies it should result 3
. I need help with point 4, below is my query. Also please suggest if there is a better way.
PUT /eg/.percolator/3
{
"query": {
"filtered": {
"filter": {
"or": [
{
"missing": {
"field": "client.db.oracle_props.@name"
}
}
]
},
"query": {
"bool": {
"must": [
{
"match": {
"client.name": "Athena"
}
},
{
"match": {
"client.db.@type": "Oracle"
}
}
]
}
}
}
}
}
Update
Can I have something like below
{
"match": {
"client.db.oracle_props[name='open_cursors'].value": 4000
}
}
More tries
I followed elasticsearch nested query and changed the mapping to nestedtype by re-indexing. Can anyone find problem why am i getting nested: NullPointerException;
?
PUT /eg/.percolator/3
{
"nested" : {
"path" : "client.db.oracle_props",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"match" : {"client.db.oracle_props.@name" : "open_cursors"}
},
{
"range" : {"client.db.oracle_props.@value" : {"lt" : 4000}}
}
]
}
}
}
}
mapping change
...
"properties": {
"@type": {
"type": "string"
},
"oracle_props": {
"type" : "nested",
"properties": {
"@name": {
"type": "string"
},
"@value": {
"type": "long"
}
}
}
}
...
Let's get into it:
- You seem to map your nested path wrong,
oracle_props
is a child item ofdb
in your example document, but not in your mapping, where it appears directly as child of your root. - You are mapping
oracle_props.@value
aslong
, but assign a textY
to it at theCREATE_PERMISSION
nested doc - You query for
range lt 4000
, which excludes 4000,lte
would fit for you
I didn't get your requirement for the missing value, hence I skipped that.
To get you to the right path, I has to simplify it a bit (since I couldn't follow all the mess in your question, sorry)
I'm not going into percolation either, and renamed everything to twitter/tweet, since this was easier for me to copy from my examples.
1) Create empty index "twitter"
curl -XDELETE 'http://localhost:9200/twitter/'
curl -XPUT 'http://localhost:9200/twitter/'
2) create geo_point mapping for the actual "tweet"
curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d '
{
"tweet": {
"properties": {
"db": {
"type": "object",
"properties": {
"@type": {
"type": "string"
},
"oracle_props": {
"type": "nested",
"properties": {
"@name": {
"type": "string"
},
"@value": {
"type": "string"
}
}
}
}
}
}
}
}'
3) Let's check if the mapping was set
curl -XGET 'http://localhost:9200/twitter/tweet/_mapping?pretty=true'
4) Post some tweets, with nested data
curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
"name": "Athena",
"version": 1,
"db": {
"@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
"oracle_props": [
{
"@name": "open_cursors",
"@value": 4000
},
{
"@name": "USER_ROLE_PRIVS_COUNT",
"@value": 1
},
{
"@name": "CREATE_PERMISSION",
"@value": "Y"
}
]
}
}'
5) Query nested only
curl -XGET localhost:9200/twitter/tweet/_search -d '{
"query": {
"nested" : {
"path" : "db.oracle_props",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"term": {
"db.oracle_props.@name": "open_cursors"
}
},
{
"range": {
"db.oracle_props.@value": {
"lte": 4000
}
}
}
]
}
}
}
}
}';
6) Query "Athena" and "Oracle"
curl -XGET localhost:9200/twitter/tweet/_search -d '{
"query" : {
"bool" : {
"must" : [
{
"match" : {"tweet.name" : "Athena"}
},
{
"match" : {"tweet.db.@type" : "Oracle"}
}
]
}
}
}'
7) Combine the former two queries
curl -XGET localhost:9200/twitter/tweet/_search -d '{
"query" : {
"bool" : {
"must" : [
{
"match" : {"tweet.name" : "Athena"}
},
{
"match" : {"tweet.db.@type" : "Oracle"}
},
{
"nested" : {
"path" : "db.oracle_props",
"score_mode" : "avg",
"query" : {
"bool" : {
"must" : [
{
"term": {
"db.oracle_props.@name": "open_cursors"
}
},
{
"range": {
"db.oracle_props.@value": {
"lte": 4000
}
}
}
]
}
}
}
}
]
}
}
}'
Results as
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 2.462332,
"hits": [
{
"_index": "twitter",
"_type": "tweet",
"_id": "1",
"_score": 2.462332,
"_source": {
"name": "Athena",
"version": 1,
"db": {
"@type": "Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 64bit",
"oracle_props": [
{
"@name": "open_cursors",
"@value": 4000
},
{
"@name": "USER_ROLE_PRIVS_COUNT",
"@value": 1
},
{
"@name": "CREATE_PERMISSION",
"@value": "Y"
}
]
}
}
}
]
}
}
这篇关于如何匹配一个数组值通过它的键值在一个键值中弹性搜索数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!