MarkLogic-在数组的每个引用中搜索

MarkLogic-在数组的每个引用中搜索,marklogic,marklogic-9,Marklogic,Marklogic 9,MarkLogic版本:9.0-6.2 我在json文档中有一个数组,如下所示。我的需要是仅当电子邮件为“时才返回此文档”test1@testmail.com对于特定的电子邮件,EmailOverrideInd为“N” "Contacts": [ { "FirstName": "FTest1", "LastName": "LTest1", "Email": "test1@testmail.com", "EmailOverrideInd": "Y" }

MarkLogic版本:9.0-6.2

我在json文档中有一个数组,如下所示。我的需要是仅当电子邮件为“时才返回此文档”test1@testmail.com对于特定的电子邮件,EmailOverrideInd为“N”

"Contacts": [
  {
    "FirstName": "FTest1", 
    "LastName": "LTest1", 
    "Email": "test1@testmail.com", 
    "EmailOverrideInd": "Y"
  },
  {
    "FirstName": "Ftest2", 
    "LastName": "Ltest2", 
    "Email": "test2@testmail.com", 
    "EmailOverrideInd": "N"
  }
]
在上面给出的示例中,查询不应返回文档,因为电子邮件的EmailOverrideInd为“N”test1@testmail.com

使用常规的cts.jsonPropertyValueQuery和cts.andQuery,我仍然可以得到文档,因为我的搜索并没有将范围限制在每个数组出现的地方

cts.search(
  cts.andQuery(
    [
      cts.collectionQuery('testcol'),
      cts.jsonPropertyValueQuery('Email', EmailAddr, ['exact']), 
      cts.jsonPropertyValueQuery('EmailOverrideInd', 'N', ['exact'])
    ]
  ),
  ['unfiltered','score-zero']
)

如何将搜索限制在每个数组出现的情况下?

如果您可以使用类似于示例的结构,则可以使用

要成功运行Unfilted,需要打开“单词位置”索引

cts.nearQuery的
1
参数意味着两个propertyQuery值需要出现在彼此的一个单词内。请注意,我使用了“ordered”选项。在这种情况下,这可能不是必需的,但我发现当我知道数据结构的顺序时,它有时会很有用


警告:我了解了在XML文档中如何计算单词,但在JSON中并没有真正使用过那么多。您可能需要调整计数,但我认为1在这里是正确的

Dave的好建议的一个替代方案是创建一个TDE索引,将数组项作为行进行投影

在打开视图时指定片段id,使用当前查询进行约束,在列上筛选感兴趣的电子邮件,然后在需要其他文档信息时加入文档(否则,只需使用行)

代码的一般形状的草图:

const docId = op.fragmentIdCol('docId');

const results = op.fromView(yourEmailsSchema, yourEmailsView, '', docId)
  .where(... your existing cts.query to narrow the candidates ...)
  .where(... boolean expression against the columns to get the exact ...)
  .joinDoc('doc', docId)
  .select('doc')
  .result();
另见:


希望这能有所帮助,

锁定匿名对象总是很棘手的。是否可以将JSON重新构造为类似于
联系人:[{Contact:{FirstName:…,…},{Contact:…}]
。这将大大简化您的查询,因为它允许在联系人上使用jsonPropertyScopeQuery。。
const docId = op.fragmentIdCol('docId');

const results = op.fromView(yourEmailsSchema, yourEmailsView, '', docId)
  .where(... your existing cts.query to narrow the candidates ...)
  .where(... boolean expression against the columns to get the exact ...)
  .joinDoc('doc', docId)
  .select('doc')
  .result();