2016-03-23 13 views
3

Aşağıdaki CTS arama sorgusu vardır: çocuklar üzerindekiCTS ve xPath her ikisi de gerekli mi?

cts:search(/parent, 
    cts:and-query((
     cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
     cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
    )) 
)/child[@attr-1 eq 'value-2' and @attr-2 eq "value-3"] 

(: Returns /parent/child elements matching criteria :) 

Ben ebeveyn bazı eleme var, hem de eleme. İstediğim sonuç sadece çocuklar. Yukarıda gördüğünüz gibi, bunu yapmak için, ben sahip olmak: Aynı kriterler mantıkla çocukları süzmek, + çocuk kriterleri

  • bu belgeyi aldıktan sonra ana kriterlere uyan belgeler için

    • Arama

    Bu, ancak cts'de aynı mantığa sahip olmamız çok aptalca görünüyor: çocuklar için xPath üzerinde yaptığım gibi. Mantık gereksiz yere kopyalanır.

    Tüm bunları cts'de yapabilmemin bir yolu var: sorgu, ve yukarıdaki örnekte olduğu gibi ek xPath ifadeleri olması gerekmez mi?


    Bu ne istiyorum benzer, ancak yorumların belirtilen sorun için çalışmaz:

    cts:search(/parent/child, 
        cts:and-query((
         cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), (: The problem is this line... I can't filter by the parent, as it is above the scope of my first parameter (/parent/rule) :) 
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
        )) 
    ) 
    
    Hala arama karşısında bile, veli sorgulayabilir
  • cevap

    3

    çocuk:

    cts:search(/parent/child, 
        cts:and-query((
         cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), 
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
        )) 
    ) 
    

    Bu filtrelenmiş arama olarak çalışır, ancak manuel zaten filtreleme yaptıklarını beri, performans kabaca eşdeğer olmalıdır.

    Güncelleme:

    Bunu test edilmiş ve yukarıdaki iddia yanlıştır. Doğru olduğunu düşündüm, ama cts:search filtresinin, aranabilir ifadeyle tam olarak eşleşmeyen sonuçları filtreleyeceği kesin. Bir ebeveyn aranabilir ifadenin kapsamı dışında olur.

    İdeali, child elemana belgelerinizi break up, ama en azından böyle örtüşen sorgular ve XPath kaldırabilirsiniz:

    cts:search(/parent/child, 
        cts:and-query((
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), 
         cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3') 
        )) 
    )[parent::parent/@attr = 'value'] 
    
    +0

    Bu benim için çalışmıyor. Aranabilir ifadesi olarak/ebeveyne sahip olduğumda, ebeveyni cts: search'den geri alırım. Aranabilir ifadesi olarak/ebeveyni/altkümeyi koyduğumda, geri bir şey alamıyorum. Cts: Sorgu hiç değişmez, tek değişmem aranabilir ifadedir./Ebeveyne/çocuğum olduğunda, işe yaramıyor. Benim varsayımım, üst öğedeki ilk öğe-öznitelik-değer-sorgusudur, herşeyi atar, çünkü aranabilir ifadenin altında değildir (?) – CtheGood

    +0

    Güncelleme için teşekkürler wst. Ayrıca, mantığı kolayca tersine çevirebilir ve ebeveynleri cts'den yakalayabilirsiniz: arama, ardından xPath kullanarak çocukları filtreleyin. Çocukları filtrelediğiniz yerde, benim durumumda, ebeveynlerden daha özgül olduğu için aslında daha hızlı olacaktır. Yine de (soruya göre) tüm bunları cts'de çözmeyi umuyordum: tamamen stilistik nedenleri araştırmak, ama belki de mümkün değil.Hesaplama maliyeti, bir cts'i filtrelemenin maliyetiyle aynı mıdır: bir xPath ifadesiyle filtreleme için olduğu gibi ara? – CtheGood

    +2

    @CtheGood Hesaplamalı olarak, cts yapmak: arama, olabildiğince çok ağır kaldırma işlemini en iyi stratejidir. Geri dönebileceği tüm sonuçlar * filtrelenmemiş * sadece dizinler kullanılarak çözülür, böylece çok hızlı olurlar. Eğer cts üzerinden filtrelemeyi kullanmanız gerekiyorsa: XPath ile arama veya manuel olarak veri tabanı 1) daha fazla doküman seçebilir, aksi halde 2) filtrelemeyi gerçekleştirmek için belleğe yükler. İlkeyi nasıl en üst düzeye çıkarmanız ve ikincisini en aza indirmeniz için genel bir kural yoktur - sadece belgelerinize bağlıdır, bu yüzden farklı yaklaşımları test etmek, yapabileceğiniz her şeyle ilgilidir. – wst

    1

    WST size cevabı verdi. Ancak, bunların hepsi filtrelemeye ihtiyaç duyuyor. MarkLogic'te fikir, bir belgenin bir 'kaydı' yansıtması gerektiğidir. Yumruk yerinde filtreleme ihtiyacından kaçınmak için belgelerinizi yeniden düzenlemek mümkün mü?

    +0

    Hayır, öyle değil. Belgelerim zaten çok basittir, her belgede yalnızca 1 derin çocukla kök öğesi vardır (yani ). Ebeveynin tüm çocukları olduğu gibi özellikleri vardır. Hedef kitlenin sadece birkaç hedeflenen çocuğunu almak istiyorum. Bunu her zaman çift mantıkla yapmak zorunda kaldım - cts: üstte arama, ardından xPath kullanarak aynı mantıkla filtreleme. Ama konsolide etmek isterim. – CtheGood

    +1

    @CtheGood David'in önerisini ilişkisel bir benzetme kullanarak ayrıntılandıran MarkLogic'te, tabloları değil, satırları belge olarak düşünmek en iyisidir. İdeal sorgu performansı için, sorgulamanız gereken veriler ile tek bir belge arasında birebir ilişki istiyorsunuz. Sizin durumunuzda, belgesini bir belge (veya parça köklerini kullanıyorum ... ama dikkatli olun) ve ebeveynlerden çocuk belgelerine sorgulamak için önemli olan herhangi bir veriyi çoğaltabilir (çoğaltabilir). Bu tür "denormalizasyon", ML'de çok yaygın bir uygulamadır. – wst

    +1

    Ve tabiki de bu dengedir. Tam bir sanat değil, ama bazı kişisel seçimler devreye giriyor. Ayrıca, MarkLogic'te küçük parçaların olmasını istemediğinizi de düşünmeniz gerekir; bu nedenle, eğer çocuk belgeleri “küçük” ise (kılavuzluk için dokümanlar bölümüne bakınız), daha sonra bunları belirli bir boyuta kadar ambalajlamak ve filtrelemeyi uygulamak uygun bir seçenektir. ML'deki üçlü bile (3 öğe ve bir ana eleman), örneğin, içe aktarıldıklarında tek tek değil, bir parça halinde yaklaşık 100 depolanır. –

    İlgili konular