Marklogic (Nodejs API) - Search documents that match 2 (or more) conditions in object array attribute

非 Y 不嫁゛ 提交于 2019-12-12 18:17:23

问题


My documents are stored in JSON in marklogic like this (I remove useless attributes for my case):

{
  documentId: '',
  languages: [{
    locale: 'en_UK',
    content: {
      translated: 'true',
    }
  }, {
    locale: 'de_DE',
    content: {
      translated: 'false',
    }
  }, {...}],
}

edit: It seem that my 'useless' attributes cause some problems. Here my detailed object.

{
  documentId: '',
  /* 4 attrs */,
  languages: [{
      locale: 'en_UK',
      attr: '',
      content: {
      /* 14 attrs */,
        translated: true,
        /* 2 or 4 attrs */,
      }
    }, {
      locale: 'de_DE',
      attr: '',
      content: {
        /* 14 attrs */,
        translated: false,
        /* 2 or 4 attrs */,
      }
    }, {...}
  ],
  /* 0 or 2 attrs */
}

I try to find all documents that have at least one object in languages where locale = 'en_UK' and content.translated = true with

var query =
  qb.where(
    qb.directory('myDocuments'),
    qb.scope(
      qb.property('languages'),
      qb.and(
        qb.scope(qb.property('code'), qb.term('en_UK')),
        qb.scope(qb.property('translated'), qb.term('true'))
      ),
      qb.fragmentScope('properties')
    )
  );

and

qb.where(
  qb.directory(myDocuments'),
  qb.scope(qb.property('languages'),
    qb.propertiesFragment(
      qb.value(
        qb.property('languages'),
        qb.and(
          qb.scope(qb.property('code'), qb.term('en_UK')),
          qb.scope(qb.property('translated'), qb.term('true'))
        )
      )
    )
  )
)

but in both cases, the query return documents that match the 2 conditions in the whole document, not in each object of languages array.

I read the documentation but I haven't found anything. Do you have any ideas how I can make my query ?

edit: I try a near query but it doesn't work. It doesn't match the good documents.

qb.where(
  qb.directory(config.marklogicConfiguration.product),
  qb.scope(qb.property('languages'),
    qb.near(
      qb.and(
        qb.scope(qb.property('code'), qb.term('ja_JP')),
        qb.scope(qb.property('translatedInTheLanguage'), qb.term('true'))
      ),
      1,
      qb.weight(0),
      qb.ordered(true)
    )
  )
)

I will ask if I can change my object structure.

edit2: Finally, I use Xquery request to get the correct result.

xdmp:directory("/product/direcory/")/languages[code eq "ja_JP" and content/translated eq "true"] ! root(.)

In my case, I use eq for content/translated condition because my boolean is stored as a string. !root(.): return the whole object, not only the language objects that match the condition [code eq "ja_JP" and content/translated eq "true"]


回答1:


Try using a near-query, one of the Location Qualifiers available in structured queries. Provide your locale and translated queries, specify a distance: 1 and ordered: true. Note that whether this works will depend on where the "useless attributes" that you removed were.

If that doesn't work, you'll probably need to introduce another layer to your structure.

{
  documentId: '',
  languages: [{
    item: {
      locale: 'en_UK',
      content: {
        translated: 'true',
      }
    }
  }, {
    item: {
      locale: 'de_DE',
      content: {
        translated: 'false',
      }
    }
  }, {...}],
}

That's not real pretty, but it would let you run a container-query.



来源:https://stackoverflow.com/questions/38573243/marklogic-nodejs-api-search-documents-that-match-2-or-more-conditions-in-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!