如何在RavenDb中创建一个索引,返回经过多个“过滤”的文档;“子值”;

如何在RavenDb中创建一个索引,返回经过多个“过滤”的文档;“子值”;,ravendb,Ravendb,我有一个包含节点列表的文档,我需要返回由多个节点过滤的文档 例如。 我有两份文件 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

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

例如。 我有两份文件

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 } 
这是实际的查询,它不会导致错误,只是不返回任何数据(但应该返回两个文档——每次使用一个where并比较结果进行验证)


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

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

或者定义一个如下所示的索引

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

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

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

i、 e:

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

假设您的enumerable nodes属性始终有两个元素,您可以尝试这样做。它不漂亮,但应该有用:

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
};

谢谢Daniel,我知道这一点,但是我希望结果集比所有文档都小。至于做一个特别的查询,我需要索引来进行过滤,如果可能的话,因为我们使用的是访问模式。对不起,我似乎误解了你的问题。你能像马特建议的那样发布一些代码或实际错误吗?你能发布你正在使用的实际代码和你收到的错误消息吗?当然,您可以在索引中使用Where(…)子句,例如,常见的场景是Where(node.name!=null)…但是,正如Danial所说,您可能不想只执行“select new{doc}”,您只需要指定将在查询中使用的字段。
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
};