我有一个json对象,像这样:
{
_id: "12345",
identifier: [
{
value: "1",
system: "system1",
text: "text!"
},
{
value: "2",
system: "system1"
}
]
}
我如何使用XDevAPI SearchConditionStr在标识符数组中寻找值+系统的特定组合?像这样,但这似乎不工作…
collection.find("'${identifier.value}' IN identifier[*].value && '${identifier.system} IN identifier[*].system")
通过使用IN
运算符,下面发生的事情基本上是对JSON_CONTAINS()
的调用。
所以,如果你调用:
collection.find(":v IN identifier[*].value && :s IN identifier[*].system")
.bind('v', '1')
.bind('s', 'system1')
.execute()
最后执行的是(简化):
JSON_CONTAINS('["1", "2"]', '"2"') AND JSON_CONTAINS('["system1", "system1"]', '"system1"')
在本例中,这两个条件都为真,并且将返回文档。
原子单元是文档(而不是该文档的切片)。因此,在您的情况下,无论value
和/或system
的值如何,您仍然在寻找相同的文档(其_id
为'12345'
的文档)。使用这样的语句,如果所有搜索值都是文档的一部分,则返回文档,如果不包含搜索值,则不返回文档。
例如,下面的语句不会产生任何结果:
collection.find(":v IN identifier[*].value && :s IN identifier[*].system")
.bind('v', '1')
.bind('s', 'system2')
.execute()
编辑:潜在的解决方案
我不认为使用CRUD API将允许执行这种"挑选",但您总是可以使用SQL。在这种情况下,想到的一种策略是使用JSON_SEARCH()
来检索与identifier[*].value
和identifier[*].system
范围内的每个值对应的路径数组,即数组索引,并使用JSON_OVERLAPS()
来确保它们是相等的。
session.sql(`select * from collection WHERE json_overlaps(json_search(json_extract(doc, '$.identifier[*].value'), 'all', ?), json_search(json_extract(doc, '$.identifier[*].system'), 'all', ?))`)
.bind('2', 'system1')
.execute()
在这种情况下,结果集将只包括identifier
数组包含至少一个JSON对象元素的文档,其中value
等于'2'
,system
等于system1
。过滤器有效地应用于单个数组项,而不是聚合,就像基本的IN
操作一样。
免责声明:我是MySQL X DevAPI Connector for Node.js的首席开发者