Как удалить повторяющиеся результаты из cts: uris, когда разные значения не работают - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть следующий код, который возвращает массив массив результатов, я пытаюсь использовать однозначные значения для удаления дубликатов, и он ничего не делает, я пытался также удалить с помощью циклических функций путем сравнения значений без успеха.

Я попытался преобразовать в «xs anyAtomicType» и использовать различные значения, которые я пытался поместить в массив json и извлечь подмассив, который я пробовал токенизировать, цитату xdmp, строку до / после и многие другие

declare function local:verify-user-uri($dir as xs:string) 
{ 
   for $each in cts:uris($dir, ())
     let $uIds := (for $d in $each  
     where contains($d, "/profile.xml")
   return $d)

   return $uIds
};    

Я получаю дублированный результат в виде:

/users/123-343-/profile.xml
/users/122-222-/profile.xml
/users/123-343-/profile.xml
/users/122-222-/profile.xml
/users/123-343-/profile.xml
/users/122-222-/profile.xml

Я ожидаю:

/users/123-343-/profile.xml
/users/122-222-/profile.xml

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

Рядом с хорошими предложениями от Мэдса я замечаю еще пару вещей о вашем коде:

  • Нет смысла перебирать $each, поскольку он содержит только один URI. Имейте в виду, что инструкция FLWOR заканчивается возвратом, который сообщает, каким должен быть результат на элемент
  • Остерегайтесь того, что первый аргумент cts:uris обозначает только начало, а не конец. Если вы вводите /aaa/, вы также получаете обратно /bbb/ и т. Д., Но не наоборот.

Честно говоря, я думаю, что вы ищете cts:uri-match() вместо этого, который уменьшил бы вашу функцию до однострочного:

declare function local:verify-user-uri($dir as xs:string) { 
  cts:uri-match($dir || "*/profile.xml")
};

НТН!

PS: я рекомендую всегда отключать отображение функций, как рекомендует Мадс. Это может предотвратить много путаницы.

0 голосов
/ 26 апреля 2019

Возможно ли, что вы просто вызывали эту функцию 3 раза и не реализовали ее?

Вы объявили $dir одним xs:string. Если ваш $dir оказался последовательностью строк одного и того же каталога, или если вы в противном случае вызывали функцию 3 раза с переменной каталога.

Это может легко произойти при включенном отображении функций (поведение по умолчанию). https://docs.marklogic.com/guide/xquery/enhanced#id_55459

Есть несколько вещей, которые вы можете сделать для диагностики:

1.) Удалите явный тип параметра $dir в функции:

declare function local:verify-user-uri($dir) 
{ 
   for $each in cts:uris($dir, ())
   let $uIds := (for $d in $each  
     where contains($d, "/profile.xml")
     return $d)
   return $uIds
};

вы получаете ошибку при выполнении cts:uris(), которая выглядит следующим образом:

[1.0-ml] XDMP-ARGTYPE:) err: XPT0004) cts: uris (("/ users /", "/ users /", "/ users /"), ()) - arg1 не имеет введите xs: string?

2.) Попробуйте отключить отображение функций, добавив в пролог следующее:

declare option xdmp:mapping "false";

и посмотрите, получите ли вы неверную ошибку приведения, например:

[1.0-ml] XDMP-AS (ошибка: XPTY0004) $ dir в виде xs: string - недопустимое приведение ("/ users /", "/ users /", "/ users /") в виде xs: string

3.) Вы также можете добавить что-нибудь в конец последовательности значений, возвращаемых функцией, чтобы указать, сколько раз она выполнялась:

declare function local:verify-user-uri($dir as xs:string) 
{ 
   for $each in cts:uris($dir, ())
   let $uIds := (for $d in $each  
     where contains($d, "/profile.xml")
     return $d)
   return $uIds, "#"
};

И посмотрите, сколько раз вы видите "#" в результате. Если их больше одного, вы вызываете функцию несколько раз.

...