【问题标题】:How can I create an index in RavenDb that returns docs filtered by more than one "subvalue"如何在 RavenDb 中创建一个索引,返回由多个“子值”过滤的文档
【发布时间】:2014-10-22 00:12:16
【问题描述】:

我有一个包含节点列表的文档,我需要返回被多个节点过滤的文档。

例如 我有 2 个文档

doc1 = {nodes: [{name:"node1", state:"1"}, {name:"node2", state:"2"]}
doc2 = {nodes: [{name:"node1", state:"1"}, {name:"node2", state:"1"]}

我希望能够创建一个索引,该索引将根据两个节点的状态选择一个文档:

也就是说,我想做这样的事情:

from doc in docs
from node in doc.nodes
where (node.name == "node1" && node.state == "1")
&& (node.name == "node2" && node.state != "2")
select new { doc }

这不起作用,我还没有找到任何做类似事情的好例子。

抱歉不清楚:

from doc in docs.CorporateInsuranceOffer
from node in doc.offerDetails.nodes 
where (node.name == "radgjof" && node.state == "state4" )  
&& (node.name == "verdlagning" && node.state != "state4" )  
select new {created = doc.offerInfo.created, offerId = doc.offerInfo.offerId, changed = doc.offerInfo.changed, kennitala = doc.offerInfo.kennitala, owner = doc.offerInfo.owner } 

这是实际的查询,它不会导致错误,它只是不返回数据(但应该返回 2 个文档——通过一次使用 1 个 where 并比较结果来验证)。

我的问题似乎是我无法在同一个文档中的 2 个不同节点上设置条件。

【问题讨论】:

  • 你能发布你正在使用的实际代码和你得到的错误信息吗?您当然可以在索引中使用 Where(..) 子句,例如常见的场景是 where (node.name != null)....
  • 但是,正如 Danial 所说,您可能不想只执行“select new { doc }”,您只需指定将在查询中使用的字段。

标签: ravendb


【解决方案1】:

当您在 RavenDB 中创建索引时,您实际上定义了一个映射函数,该函数将从您的文档中映射/提取一些信息,并将它们传递给 Lucene 以供以后查询。重要的是要了解 linq 索引定义中的“选择”应该选择您以后要查询的条件。这意味着您需要选择要查询的属性,而不是整个文档本身。

要么定义一个看起来像这样的索引

from doc in docs
from node in doc.nodes
select new { node.name, node.state }

或者更好的是,只需查询您需要的任何内容(无需预先定义索引),然后让 RavenDB 找出您需要的索引。

【讨论】:

  • 谢谢丹尼尔,我知道这一点,但是我希望结果集小于所有文档。至于进行临时查询,由于我们使用的访问模式,如果可能的话,我需要索引来进行过滤。
  • 对不起,我好像误解了你的问题。您能按照 Matt 的建议发布一些代码或实际错误吗?
【解决方案2】:

嗯,一个问题是您的查询永远不会返回结果,因为节点名称永远无法测试同一属性上的两个单独值是否为真。

即:

(node.name == "node1" && node.state == "1") && (node.name == "node2" && node.state != "2")

这里的“节点”在所有情况下都是同一个实体。此查询将始终返回一个空集。

假设你的可枚举节点属性总是有两个元素,你可以试试这个。它不漂亮但应该可以工作:

from doc in docs
where (doc.nodes.ElementAt(0).name == "radgjof" && doc.nodes.ElementAt(0).state == "state4")
&& (doc.nodes.ElementAt(1).name == "verdlagning" && doc.nodes.ElementAt(1).state == "state4")
select new
{
    doc
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    相关资源
    最近更新 更多