Azure DocumentDB — запрос не возвращает результатов

Поддерживается ли приведенный ниже запрос в Azure DocumentDB? Он не возвращает документы.

Variables values at runtime:
  1. collectionLink = "<link for my collection>"
  2. feedOptions = new FeedOptions { MaxItemCount = 2 }
  3. name = "chris"

client.CreateDocumentQuery<T>(collectionLink, feedOptions).Where(m => (m.Status == "Foo" && (m.Black.Name == null || m.Black.Name != name) && (m.White.Name == null || m.White.Name != name)));

Я протестировал более простые запросы, такие как приведенный ниже, оба из которых возвращают ожидаемые результаты.

client.CreateDocumentQuery<T>(collectionLink, feedOptions).Where(m => m.Status == "Foo");

client.CreateDocumentQuery<T>(collectionLink, feedOptions).Where(m => m.Status == "Foo").Where(m => m.Size == 19);

Наконец, я убедился, что есть документы, соответствующие критериям фильтра проблемного запроса:

{
  "id": "1992db52-c9c6-4496-aaaa-f8cb83a8c6b0",
  "status": "Foo",
  "size": 19,
  "black": {
    "name": "charlie"
  },
  "white": {},
}

Спасибо.


person Scott Lin    schedule 18.11.2014    source источник


Ответы (2)


Оказывается, проверка «m.White.Name == null || m.White.Name != name» проблематична, поскольку поле «Имя» не существует в документе в БД.

Когда документ редактируется следующим образом, запрос возвращает его. Обратите внимание на явное нулевое значение поля Name.

{
  "id": "1992db52-c9c6-4496-aaaa-f8cb83a8c6b0",
  "status": "Foo",
  "size": 19,
  "black": {
    "name": "charlie"
  },
  "white": {
    "name": null
  },
}
person Scott Lin    schedule 18.11.2014

Запрос может быть написан для обработки отсутствующих свойств с использованием пользовательских функций DocumentDB следующим образом. DocumentDB использует семантику JavaScript, и явный нуль отличается от отсутствующего свойства («неопределенного») в JavaScript. Проверить явное значение null просто (== null, как и ваш запрос), но для запроса поля, которое может существовать или не существовать в DocumentDB, вы должны сначала создать пользовательскую функцию для ISDEFINED:

function ISDEFINED(doc, prop) {
    return doc[prop] !== undefined;   
}

А затем используйте его в запросе DocumentDB, например:

client.CreateDocumentQuery<T>(
    collectionLink, 
   "SELECT * FROM docs m WHERE m.Status == "Foo" AND (ISDEFINED(m.white, "name") OR m.white.name != name)");

Надеюсь это поможет. Обратите внимание, что, поскольку != и пользовательские функции требуют сканирования, для производительности/масштаба рекомендуется всегда использовать их только в запросах с другими фильтрами.

person Aravind Krishna R.    schedule 19.11.2014
comment
Теперь я вижу IS_DEFINED(expr) как стандартную функцию проверки типов. Было ли это добавлено между тем, когда вы написали выше, и сейчас, или есть что-то другое в вашей UDF и IS_DEFINED, чего я не вижу? - person Larry Maccherone; 24.08.2015